Repository: VIA-Research/uPIMulator Branch: main Commit: 870d916334e9 Files: 2582 Total size: 229.4 MB Directory structure: gitextract_ry7k9cpr/ ├── .gitignore ├── LICENSE ├── README.md ├── assets/ │ ├── figure5_mem_util_calculator.xlsx │ ├── figure7_active_tasklet_breakdown.xlsx │ └── figure9_instruction_mix.xlsx ├── golang/ │ ├── README.md │ └── uPIMulator/ │ ├── benchmark/ │ │ ├── BS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── bs_omp.c │ │ │ │ │ └── timer.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── binary_search.cu │ │ │ │ ├── binary_search.h │ │ │ │ ├── cpu_lib.py │ │ │ │ ├── cu_lib_import.py │ │ │ │ └── run.py │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── CMakeLists.txt │ │ ├── GEMV/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── gemv_openmp.c │ │ │ │ │ └── gemv_utils.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── gemv.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-L/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-S/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── input/ │ │ │ │ │ └── image_VanHateren.iml │ │ │ │ ├── kernel.cpp │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── partitioner.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── MLP/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── mlp_openmp.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── mlp.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── RED/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-RSS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-SSA/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SEL/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── select.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── TRNS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── kernel.cpp │ │ │ │ │ ├── kernel.h │ │ │ │ │ ├── main.cpp │ │ │ │ │ └── support/ │ │ │ │ │ ├── common.h │ │ │ │ │ ├── setup.h │ │ │ │ │ ├── timer.h │ │ │ │ │ └── verify.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── TS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── UNI/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── unique.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── VA/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── vec_add.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ └── build.py │ ├── docker/ │ │ └── Dockerfile │ ├── go.mod │ ├── go.sum │ ├── script/ │ │ ├── build.py │ │ ├── format.py │ │ ├── run_validation.sh │ │ └── visualize.py │ ├── sdk/ │ │ ├── CMakeLists.txt │ │ ├── build.py │ │ ├── misc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── accessMramFromDpu.c │ │ │ ├── coreDump.c │ │ │ ├── crt0.c │ │ │ ├── dpu.lds │ │ │ ├── internalStateReset.c │ │ │ ├── linkerScript.lds │ │ │ ├── restoreRegisters.c │ │ │ └── restore_carry_and_zero_flag.h │ │ ├── stdlib/ │ │ │ ├── CMakeLists.txt │ │ │ ├── abort.c │ │ │ ├── assert.h │ │ │ ├── atoi.c │ │ │ ├── atol.c │ │ │ ├── ctype.h │ │ │ ├── errno.c │ │ │ ├── errno.h │ │ │ ├── exit.c │ │ │ ├── inttypes.h │ │ │ ├── iso646.h │ │ │ ├── limits.h │ │ │ ├── memchr.c │ │ │ ├── memcmp.c │ │ │ ├── memcpy.c │ │ │ ├── memmove.c │ │ │ ├── memmram_utils.h │ │ │ ├── memset.c │ │ │ ├── stdalign.h │ │ │ ├── stdarg.h │ │ │ ├── stdbool.h │ │ │ ├── stddef.h │ │ │ ├── stdint.h │ │ │ ├── stdio.c │ │ │ ├── stdio.h │ │ │ ├── stdlib.h │ │ │ ├── stdnoreturn.h │ │ │ ├── stpcpy.c │ │ │ ├── stpncpy.c │ │ │ ├── strcat.c │ │ │ ├── strchr.c │ │ │ ├── strcmp.c │ │ │ ├── strcpy.c │ │ │ ├── strcspn.c │ │ │ ├── strdup.c │ │ │ ├── strerror.c │ │ │ ├── string.h │ │ │ ├── strlen.c │ │ │ ├── strlwr.c │ │ │ ├── strncat.c │ │ │ ├── strncmp.c │ │ │ ├── strncpy.c │ │ │ ├── strndup.c │ │ │ ├── strnlen.c │ │ │ ├── strpbrk.c │ │ │ ├── strrchr.c │ │ │ ├── strrev.c │ │ │ ├── strsep.c │ │ │ ├── strspn.c │ │ │ ├── strstr.c │ │ │ ├── strtok_r.c │ │ │ ├── strtol.c │ │ │ └── strupr.c │ │ └── syslib/ │ │ ├── CMakeLists.txt │ │ ├── absvdi2.c │ │ ├── absvsi2.c │ │ ├── adddf3.c │ │ ├── addsf3.c │ │ ├── addvdi3.c │ │ ├── addvsi3.c │ │ ├── alloc.c │ │ ├── alloc.h │ │ ├── ashldi3.c │ │ ├── ashrdi3.c │ │ ├── atomic_bit.h │ │ ├── atomics.c │ │ ├── attributes.h │ │ ├── barrier.c │ │ ├── barrier.h │ │ ├── bswapdi2.c │ │ ├── bswapsi2.c │ │ ├── buddy_alloc.c │ │ ├── buddy_alloc.h │ │ ├── buddy_realloc.c │ │ ├── built_ins.h │ │ ├── clzdi2.c │ │ ├── clzsi2.c │ │ ├── cmpdi2.c │ │ ├── comparedf2.c │ │ ├── comparesf2.c │ │ ├── ctzdi2.c │ │ ├── ctzsi2.c │ │ ├── defs.c │ │ ├── defs.h │ │ ├── devprivate.h │ │ ├── div32.c │ │ ├── divdf3.c │ │ ├── divdi3.c │ │ ├── divmodsi4.c │ │ ├── divsf3.c │ │ ├── divsi3.c │ │ ├── dpuconst.h │ │ ├── dpufault.h │ │ ├── dpuruntime.h │ │ ├── extendhfsf2.c │ │ ├── extendsfdf2.c │ │ ├── ffsdi2.c │ │ ├── ffssi2.c │ │ ├── ffsti2.c │ │ ├── fixdfdi.c │ │ ├── fixdfsi.c │ │ ├── fixsfdi.c │ │ ├── fixsfsi.c │ │ ├── fixunsdfdi.c │ │ ├── fixunsdfsi.c │ │ ├── fixunssfdi.c │ │ ├── fixunssfsi.c │ │ ├── float.h │ │ ├── floatdidf.c │ │ ├── floatdisf.c │ │ ├── floatsidf.c │ │ ├── floatsisf.c │ │ ├── floatundidf.c │ │ ├── floatundisf.c │ │ ├── floatunsidf.c │ │ ├── floatunsisf.c │ │ ├── fp_add_impl.inc │ │ ├── fp_extend.h │ │ ├── fp_extend_impl.inc │ │ ├── fp_fixint_impl.inc │ │ ├── fp_fixuint_impl.inc │ │ ├── fp_lib.h │ │ ├── fp_mul_impl.inc │ │ ├── fp_trunc.h │ │ ├── fp_trunc_impl.inc │ │ ├── fsb_allocator.c │ │ ├── fsb_allocator.h │ │ ├── handshake.c │ │ ├── handshake.h │ │ ├── int_endianness.h │ │ ├── int_lib.h │ │ ├── int_math.h │ │ ├── int_types.h │ │ ├── int_util.c │ │ ├── int_util.h │ │ ├── listener.c │ │ ├── lshrdi3.c │ │ ├── macro_utils.h │ │ ├── mcount.c │ │ ├── moddi3.c │ │ ├── modsi3.c │ │ ├── mram.h │ │ ├── mul32.c │ │ ├── mul64.c │ │ ├── muldc3.c │ │ ├── muldf3.c │ │ ├── mulodi4.c │ │ ├── mulosi4.c │ │ ├── mulsf3.c │ │ ├── mulvdi3.c │ │ ├── mulvsi3.c │ │ ├── mutex.h │ │ ├── negdf2.c │ │ ├── negdi2.c │ │ ├── negsf2.c │ │ ├── negvdi2.c │ │ ├── negvsi2.c │ │ ├── paritydi2.c │ │ ├── paritysi2.c │ │ ├── perfcounter.c │ │ ├── perfcounter.h │ │ ├── popcountdi2.c │ │ ├── popcountsi2.c │ │ ├── powidf2.c │ │ ├── powisf2.c │ │ ├── profiling.c │ │ ├── profiling.h │ │ ├── profiling_internals.h │ │ ├── sem.c │ │ ├── sem.h │ │ ├── seqread.h │ │ ├── seqread.inc │ │ ├── seqread1024.c │ │ ├── seqread128.c │ │ ├── seqread256.c │ │ ├── seqread32.c │ │ ├── seqread512.c │ │ ├── seqread64.c │ │ ├── soft_cache.c │ │ ├── soft_cache.h │ │ ├── subdf3.c │ │ ├── subsf3.c │ │ ├── subvdi3.c │ │ ├── subvsi3.c │ │ ├── sysdef.h │ │ ├── truncdfhf2.c │ │ ├── truncdfsf2.c │ │ ├── truncsfhf2.c │ │ ├── ucmpdi2.c │ │ ├── udiv64.c │ │ ├── udivdi3.c │ │ ├── udivmodsi4.c │ │ ├── udivsi3.c │ │ ├── umoddi3.c │ │ ├── umodsi3.c │ │ └── waitqueue.c │ └── src/ │ ├── abi/ │ │ ├── encoding/ │ │ │ ├── ascii_encoder.go │ │ │ └── byte_stream.go │ │ └── word/ │ │ ├── intermediate.go │ │ └── word.go │ ├── assembler/ │ │ ├── assemblable.go │ │ ├── assembler.go │ │ └── prim/ │ │ ├── bs.go │ │ ├── gemv.go │ │ ├── hst_l.go │ │ ├── hst_s.go │ │ ├── mlp.go │ │ ├── red.go │ │ ├── scan_rss.go │ │ ├── scan_ssa.go │ │ ├── sel.go │ │ ├── trns.go │ │ ├── ts.go │ │ ├── uni.go │ │ └── va.go │ ├── compiler/ │ │ └── compiler.go │ ├── core/ │ │ ├── job.go │ │ └── thread_pool.go │ ├── linker/ │ │ ├── analyze_liveness_job.go │ │ ├── kernel/ │ │ │ ├── directive/ │ │ │ │ ├── ascii_directive.go │ │ │ │ ├── asciz_directive.go │ │ │ │ ├── byte_directive.go │ │ │ │ ├── long_directive.go │ │ │ │ ├── quad_directive.go │ │ │ │ ├── short_directive.go │ │ │ │ └── zero_directive.go │ │ │ ├── encodable.go │ │ │ ├── executable.go │ │ │ ├── instruction/ │ │ │ │ ├── cc/ │ │ │ │ │ ├── acquire_cc.go │ │ │ │ │ ├── add_nz_cc.go │ │ │ │ │ ├── boot_cc.go │ │ │ │ │ ├── cc.go │ │ │ │ │ ├── const_cc_ge0.go │ │ │ │ │ ├── const_cc_geu.go │ │ │ │ │ ├── const_cc_zero.go │ │ │ │ │ ├── count_nz_cc.go │ │ │ │ │ ├── div_cc.go │ │ │ │ │ ├── div_nz_cc.go │ │ │ │ │ ├── ext_sub_set_cc.go │ │ │ │ │ ├── false_cc.go │ │ │ │ │ ├── imm_shift_nz_cc.go │ │ │ │ │ ├── log_nz_cc.go │ │ │ │ │ ├── log_set_cc.go │ │ │ │ │ ├── mul_nz_cc.go │ │ │ │ │ ├── no_cc.go │ │ │ │ │ ├── release_cc.go │ │ │ │ │ ├── shift_nz_cc.go │ │ │ │ │ ├── sub_nz_cc.go │ │ │ │ │ ├── sub_set_cc.go │ │ │ │ │ ├── true_cc.go │ │ │ │ │ └── true_false_cc.go │ │ │ │ ├── endian.go │ │ │ │ ├── exception.go │ │ │ │ ├── flag.go │ │ │ │ ├── instruction.go │ │ │ │ ├── op_code.go │ │ │ │ ├── reg_descriptor/ │ │ │ │ │ ├── gp_reg_descriptor.go │ │ │ │ │ ├── pair_reg_descriptor.go │ │ │ │ │ ├── sp_reg_descriptor.go │ │ │ │ │ └── src_reg_descriptor.go │ │ │ │ └── suffix.go │ │ │ ├── kernel.go │ │ │ ├── label.go │ │ │ ├── liveness.go │ │ │ ├── relocatable.go │ │ │ └── section.go │ │ ├── lex_job.go │ │ ├── lexer/ │ │ │ ├── keyword_factory.go │ │ │ ├── lexer.go │ │ │ ├── regex.go │ │ │ ├── regex_factory.go │ │ │ ├── token.go │ │ │ ├── token_stream.go │ │ │ └── tokenizer.go │ │ ├── linker.go │ │ ├── logic/ │ │ │ ├── instruction_assigner.go │ │ │ ├── label_assigner.go │ │ │ ├── linker_constant.go │ │ │ ├── linker_script.go │ │ │ ├── liveness_analyzer.go │ │ │ └── set_assigner.go │ │ ├── parse_job.go │ │ └── parser/ │ │ ├── ast.go │ │ ├── expr/ │ │ │ ├── binary_add_expr.go │ │ │ ├── binary_sub_expr.go │ │ │ ├── ci_op_code_expr.go │ │ │ ├── condition_expr.go │ │ │ ├── ddci_op_code_expr.go │ │ │ ├── dma_rri_op_code_expr.go │ │ │ ├── drdici_op_code_expr.go │ │ │ ├── endian_expr.go │ │ │ ├── expr.go │ │ │ ├── i_op_code_expr.go │ │ │ ├── jump_op_code_expr.go │ │ │ ├── load_op_code_expr.go │ │ │ ├── negative_number_expr.go │ │ │ ├── primary_expr.go │ │ │ ├── program_counter_expr.go │ │ │ ├── r_op_code_expr.go │ │ │ ├── rici_op_code_expr.go │ │ │ ├── rr_op_code_expr.go │ │ │ ├── rri_op_code_expr.go │ │ │ ├── rrri_op_code_expr.go │ │ │ ├── section_name_expr.go │ │ │ ├── section_type_expr.go │ │ │ ├── src_reg_expr.go │ │ │ ├── store_op_code_expr.go │ │ │ ├── suffix_expr.go │ │ │ └── symbol_type.go │ │ ├── parser.go │ │ ├── rule.go │ │ ├── stack.go │ │ ├── stack_item.go │ │ ├── stmt/ │ │ │ ├── directive/ │ │ │ │ ├── addrsig_stmt.go │ │ │ │ ├── addrsig_sym_stmt.go │ │ │ │ ├── ascii_stmt.go │ │ │ │ ├── asciz_stmt.go │ │ │ │ ├── byte_stmt.go │ │ │ │ ├── cfi_def_cfa_offset_stmt.go │ │ │ │ ├── cfi_endproc.go │ │ │ │ ├── cfi_offset_stmt.go │ │ │ │ ├── cfi_sections_stmt.go │ │ │ │ ├── cfi_startproc_stmt.go │ │ │ │ ├── file_number_stmt.go │ │ │ │ ├── file_string_stmt.go │ │ │ │ ├── global_stmt.go │ │ │ │ ├── loc_is_stmt_stmt.go │ │ │ │ ├── loc_number_stmt.go │ │ │ │ ├── loc_prologue_end_stmt.go │ │ │ │ ├── long_program_counter.go │ │ │ │ ├── long_section_name_stmt.go │ │ │ │ ├── p2_align_stmt.go │ │ │ │ ├── quad_stmt.go │ │ │ │ ├── section_identifier_number_stmt.go │ │ │ │ ├── section_identifier_stmt.go │ │ │ │ ├── section_stack_sizes_stmt.go │ │ │ │ ├── section_string_number_stmt.go │ │ │ │ ├── section_string_stmt.go │ │ │ │ ├── set_stmt.go │ │ │ │ ├── short_stmt.go │ │ │ │ ├── size_stmt.go │ │ │ │ ├── text_stmt.go │ │ │ │ ├── type_stmt.go │ │ │ │ ├── weak_stmt.go │ │ │ │ ├── zero_double_number_stmt.go │ │ │ │ └── zero_single_number_stmt.go │ │ │ ├── instruction/ │ │ │ │ ├── ci_stmt.go │ │ │ │ ├── ddci_stmt.go │ │ │ │ ├── dma_rri_stmt.go │ │ │ │ ├── drdici_stmt.go │ │ │ │ ├── edri_stmt.go │ │ │ │ ├── erid_stmt.go │ │ │ │ ├── erii_stmt.go │ │ │ │ ├── erir_stmt.go │ │ │ │ ├── erri_stmt.go │ │ │ │ ├── i_stmt.go │ │ │ │ ├── nop_stmt.go │ │ │ │ ├── r_stmt.go │ │ │ │ ├── rci_stmt.go │ │ │ │ ├── rici_stmt.go │ │ │ │ ├── rir_stmt.go │ │ │ │ ├── rirc_stmt.go │ │ │ │ ├── rirci_stmt.go │ │ │ │ ├── rr_stmt.go │ │ │ │ ├── rrc_stmt.go │ │ │ │ ├── rrci_stmt.go │ │ │ │ ├── rri_stmt.go │ │ │ │ ├── rric_stmt.go │ │ │ │ ├── rrici_stmt.go │ │ │ │ ├── rrr_stmt.go │ │ │ │ ├── rrrc_stmt.go │ │ │ │ ├── rrrci_stmt.go │ │ │ │ ├── rrri_stmt.go │ │ │ │ ├── rrrici_stmt.go │ │ │ │ ├── s_erri_stmt.go │ │ │ │ ├── s_r_stmt.go │ │ │ │ ├── s_rci_stmt.go │ │ │ │ ├── s_rirc_stmt.go │ │ │ │ ├── s_rirci_stmt.go │ │ │ │ ├── s_rr_stmt.go │ │ │ │ ├── s_rrc_stmt.go │ │ │ │ ├── s_rrci_stmt.go │ │ │ │ ├── s_rri_stmt.go │ │ │ │ ├── s_rric_stmt.go │ │ │ │ ├── s_rrici_stmt.go │ │ │ │ ├── s_rrr_stmt.go │ │ │ │ ├── s_rrrc_stmt.go │ │ │ │ ├── s_rrrci_stmt.go │ │ │ │ ├── s_rrri_stmt.go │ │ │ │ └── s_rrrici_stmt.go │ │ │ ├── label_stmt.go │ │ │ ├── stmt.go │ │ │ └── sugar/ │ │ │ ├── bkp_stmt.go │ │ │ ├── boot_ri_stmt.go │ │ │ ├── call_ri_stmt.go │ │ │ ├── call_rr_stmt.go │ │ │ ├── div_step_drdi_stmt.go │ │ │ ├── jeq_rii_stmt.go │ │ │ ├── jeq_rri_stmt.go │ │ │ ├── jnz_ri_stmt.go │ │ │ ├── jump_i_stmt.go │ │ │ ├── jump_r_stmt.go │ │ │ ├── lbs_rri_stmt.go │ │ │ ├── lbs_s_rri_stmt.go │ │ │ ├── ld_dri_stmt.go │ │ │ ├── movd_dd_stmt.go │ │ │ ├── move_ri_stmt.go │ │ │ ├── move_rici_stmt.go │ │ │ ├── move_s_ri_stmt.go │ │ │ ├── move_s_rici_stmt.go │ │ │ ├── sb_id_ri_stmt.go │ │ │ ├── sb_id_rii_stmt.go │ │ │ ├── sb_rir_stmt.go │ │ │ ├── sd_rid_stmt.go │ │ │ ├── stop_stmt.go │ │ │ └── time_cfg_r_stmt.go │ │ ├── table.go │ │ └── walker.go │ ├── main.go │ ├── misc/ │ │ ├── command_line_option.go │ │ ├── command_line_parser.go │ │ ├── command_line_validator.go │ │ ├── config_loader.go │ │ ├── config_validator.go │ │ ├── file_dumper.go │ │ ├── file_scanner.go │ │ └── stat_factory.go │ └── simulator/ │ ├── channel/ │ │ ├── channel.go │ │ ├── channel_message.go │ │ └── channel_message_q.go │ ├── cycle_job.go │ ├── dpu/ │ │ ├── dpu.go │ │ ├── dram/ │ │ │ ├── dma_command.go │ │ │ ├── dma_command_q.go │ │ │ ├── memory_command.go │ │ │ ├── memory_command_q.go │ │ │ ├── memory_controller.go │ │ │ ├── memory_scheduler.go │ │ │ ├── mram.go │ │ │ ├── row_buffer.go │ │ │ └── wordline.go │ │ ├── logic/ │ │ │ ├── alu.go │ │ │ ├── cycle_rule.go │ │ │ ├── dma.go │ │ │ ├── instruction_q.go │ │ │ ├── logic.go │ │ │ ├── operand_collector.go │ │ │ ├── pipeline.go │ │ │ ├── reg_set.go │ │ │ ├── thread.go │ │ │ ├── thread_q.go │ │ │ └── thread_scheduler.go │ │ ├── reg/ │ │ │ ├── condition_reg.go │ │ │ ├── exception_reg.go │ │ │ ├── flag_reg.go │ │ │ ├── gp_reg.go │ │ │ ├── pc_reg.go │ │ │ ├── reg_file.go │ │ │ └── sp_reg.go │ │ └── sram/ │ │ ├── atomic.go │ │ ├── iram.go │ │ ├── lock.go │ │ └── wram.go │ ├── host/ │ │ ├── channel_transfer_read_job.go │ │ ├── channel_transfer_write_job.go │ │ ├── chunk.go │ │ ├── cycle_job.go │ │ ├── dma_transfer_to_atomic_job.go │ │ ├── dma_transfer_to_iram_job.go │ │ ├── dma_transfer_to_mram_job.go │ │ ├── dma_transfer_to_wram_job.go │ │ └── host.go │ ├── rank/ │ │ └── rank.go │ └── simulator.go ├── golang_vm/ │ ├── README.md │ └── uPIMulator/ │ ├── benchmark/ │ │ ├── BS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── bs_omp.c │ │ │ │ │ └── timer.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── binary_search.cu │ │ │ │ ├── binary_search.h │ │ │ │ ├── cpu_lib.py │ │ │ │ ├── cu_lib_import.py │ │ │ │ └── run.py │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── CMakeLists.txt │ │ ├── GEMV/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── gemv_openmp.c │ │ │ │ │ └── gemv_utils.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── gemv.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-L/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-S/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── input/ │ │ │ │ │ └── image_VanHateren.iml │ │ │ │ ├── kernel.cpp │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── partitioner.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── MLP/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── mlp_openmp.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── mlp.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── RED/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-RSS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-SSA/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SEL/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── select.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── TRNS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── kernel.cpp │ │ │ │ │ ├── kernel.h │ │ │ │ │ ├── main.cpp │ │ │ │ │ └── support/ │ │ │ │ │ ├── common.h │ │ │ │ │ ├── setup.h │ │ │ │ │ ├── timer.h │ │ │ │ │ └── verify.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── TS/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── UNI/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── unique.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── VA/ │ │ │ ├── CMakeLists.txt │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── vec_add.cu │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── VA_SIMPLE/ │ │ │ ├── CMakeLists.txt │ │ │ ├── dpu/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── task.c │ │ │ └── host/ │ │ │ ├── CMakeLists.txt │ │ │ └── app.c │ │ └── build.py │ ├── docker/ │ │ └── Dockerfile │ ├── go.mod │ ├── script/ │ │ ├── build.py │ │ └── format.py │ ├── sdk/ │ │ ├── CMakeLists.txt │ │ ├── build.py │ │ ├── misc/ │ │ │ ├── CMakeLists.txt │ │ │ ├── accessMramFromDpu.c │ │ │ ├── coreDump.c │ │ │ ├── crt0.c │ │ │ ├── dpu.lds │ │ │ ├── internalStateReset.c │ │ │ ├── linkerScript.lds │ │ │ ├── restoreRegisters.c │ │ │ └── restore_carry_and_zero_flag.h │ │ ├── stdlib/ │ │ │ ├── CMakeLists.txt │ │ │ ├── abort.c │ │ │ ├── assert.h │ │ │ ├── atoi.c │ │ │ ├── atol.c │ │ │ ├── ctype.h │ │ │ ├── errno.c │ │ │ ├── errno.h │ │ │ ├── exit.c │ │ │ ├── inttypes.h │ │ │ ├── iso646.h │ │ │ ├── limits.h │ │ │ ├── memchr.c │ │ │ ├── memcmp.c │ │ │ ├── memcpy.c │ │ │ ├── memmove.c │ │ │ ├── memmram_utils.h │ │ │ ├── memset.c │ │ │ ├── stdalign.h │ │ │ ├── stdarg.h │ │ │ ├── stdbool.h │ │ │ ├── stddef.h │ │ │ ├── stdint.h │ │ │ ├── stdio.c │ │ │ ├── stdio.h │ │ │ ├── stdlib.h │ │ │ ├── stdnoreturn.h │ │ │ ├── stpcpy.c │ │ │ ├── stpncpy.c │ │ │ ├── strcat.c │ │ │ ├── strchr.c │ │ │ ├── strcmp.c │ │ │ ├── strcpy.c │ │ │ ├── strcspn.c │ │ │ ├── strdup.c │ │ │ ├── strerror.c │ │ │ ├── string.h │ │ │ ├── strlen.c │ │ │ ├── strlwr.c │ │ │ ├── strncat.c │ │ │ ├── strncmp.c │ │ │ ├── strncpy.c │ │ │ ├── strndup.c │ │ │ ├── strnlen.c │ │ │ ├── strpbrk.c │ │ │ ├── strrchr.c │ │ │ ├── strrev.c │ │ │ ├── strsep.c │ │ │ ├── strspn.c │ │ │ ├── strstr.c │ │ │ ├── strtok_r.c │ │ │ ├── strtol.c │ │ │ └── strupr.c │ │ └── syslib/ │ │ ├── CMakeLists.txt │ │ ├── absvdi2.c │ │ ├── absvsi2.c │ │ ├── adddf3.c │ │ ├── addsf3.c │ │ ├── addvdi3.c │ │ ├── addvsi3.c │ │ ├── alloc.c │ │ ├── alloc.h │ │ ├── ashldi3.c │ │ ├── ashrdi3.c │ │ ├── atomic_bit.h │ │ ├── atomics.c │ │ ├── attributes.h │ │ ├── barrier.c │ │ ├── barrier.h │ │ ├── bswapdi2.c │ │ ├── bswapsi2.c │ │ ├── buddy_alloc.c │ │ ├── buddy_alloc.h │ │ ├── buddy_realloc.c │ │ ├── built_ins.h │ │ ├── clzdi2.c │ │ ├── clzsi2.c │ │ ├── cmpdi2.c │ │ ├── comparedf2.c │ │ ├── comparesf2.c │ │ ├── ctzdi2.c │ │ ├── ctzsi2.c │ │ ├── defs.c │ │ ├── defs.h │ │ ├── devprivate.h │ │ ├── div32.c │ │ ├── divdf3.c │ │ ├── divdi3.c │ │ ├── divmodsi4.c │ │ ├── divsf3.c │ │ ├── divsi3.c │ │ ├── dpuconst.h │ │ ├── dpufault.h │ │ ├── dpuruntime.h │ │ ├── extendhfsf2.c │ │ ├── extendsfdf2.c │ │ ├── ffsdi2.c │ │ ├── ffssi2.c │ │ ├── ffsti2.c │ │ ├── fixdfdi.c │ │ ├── fixdfsi.c │ │ ├── fixsfdi.c │ │ ├── fixsfsi.c │ │ ├── fixunsdfdi.c │ │ ├── fixunsdfsi.c │ │ ├── fixunssfdi.c │ │ ├── fixunssfsi.c │ │ ├── float.h │ │ ├── floatdidf.c │ │ ├── floatdisf.c │ │ ├── floatsidf.c │ │ ├── floatsisf.c │ │ ├── floatundidf.c │ │ ├── floatundisf.c │ │ ├── floatunsidf.c │ │ ├── floatunsisf.c │ │ ├── fp_add_impl.inc │ │ ├── fp_extend.h │ │ ├── fp_extend_impl.inc │ │ ├── fp_fixint_impl.inc │ │ ├── fp_fixuint_impl.inc │ │ ├── fp_lib.h │ │ ├── fp_mul_impl.inc │ │ ├── fp_trunc.h │ │ ├── fp_trunc_impl.inc │ │ ├── fsb_allocator.c │ │ ├── fsb_allocator.h │ │ ├── handshake.c │ │ ├── handshake.h │ │ ├── int_endianness.h │ │ ├── int_lib.h │ │ ├── int_math.h │ │ ├── int_types.h │ │ ├── int_util.c │ │ ├── int_util.h │ │ ├── listener.c │ │ ├── lshrdi3.c │ │ ├── macro_utils.h │ │ ├── mcount.c │ │ ├── moddi3.c │ │ ├── modsi3.c │ │ ├── mram.h │ │ ├── mul32.c │ │ ├── mul64.c │ │ ├── muldc3.c │ │ ├── muldf3.c │ │ ├── mulodi4.c │ │ ├── mulosi4.c │ │ ├── mulsf3.c │ │ ├── mulvdi3.c │ │ ├── mulvsi3.c │ │ ├── mutex.h │ │ ├── negdf2.c │ │ ├── negdi2.c │ │ ├── negsf2.c │ │ ├── negvdi2.c │ │ ├── negvsi2.c │ │ ├── paritydi2.c │ │ ├── paritysi2.c │ │ ├── perfcounter.c │ │ ├── perfcounter.h │ │ ├── popcountdi2.c │ │ ├── popcountsi2.c │ │ ├── powidf2.c │ │ ├── powisf2.c │ │ ├── profiling.c │ │ ├── profiling.h │ │ ├── profiling_internals.h │ │ ├── sem.c │ │ ├── sem.h │ │ ├── seqread.h │ │ ├── seqread.inc │ │ ├── seqread1024.c │ │ ├── seqread128.c │ │ ├── seqread256.c │ │ ├── seqread32.c │ │ ├── seqread512.c │ │ ├── seqread64.c │ │ ├── soft_cache.c │ │ ├── soft_cache.h │ │ ├── subdf3.c │ │ ├── subsf3.c │ │ ├── subvdi3.c │ │ ├── subvsi3.c │ │ ├── sysdef.h │ │ ├── truncdfhf2.c │ │ ├── truncdfsf2.c │ │ ├── truncsfhf2.c │ │ ├── ucmpdi2.c │ │ ├── udiv64.c │ │ ├── udivdi3.c │ │ ├── udivmodsi4.c │ │ ├── udivsi3.c │ │ ├── umoddi3.c │ │ ├── umodsi3.c │ │ └── waitqueue.c │ └── src/ │ ├── device/ │ │ ├── abi/ │ │ │ ├── intermediate.go │ │ │ └── word.go │ │ ├── compiler/ │ │ │ └── compiler.go │ │ ├── core/ │ │ │ ├── job.go │ │ │ └── thread_pool.go │ │ ├── linker/ │ │ │ ├── analyze_liveness_job.go │ │ │ ├── kernel/ │ │ │ │ ├── directive/ │ │ │ │ │ ├── ascii_directive.go │ │ │ │ │ ├── asciz_directive.go │ │ │ │ │ ├── byte_directive.go │ │ │ │ │ ├── long_directive.go │ │ │ │ │ ├── quad_directive.go │ │ │ │ │ ├── short_directive.go │ │ │ │ │ └── zero_directive.go │ │ │ │ ├── encodable.go │ │ │ │ ├── executable.go │ │ │ │ ├── instruction/ │ │ │ │ │ ├── cc/ │ │ │ │ │ │ ├── acquire_cc.go │ │ │ │ │ │ ├── add_nz_cc.go │ │ │ │ │ │ ├── boot_cc.go │ │ │ │ │ │ ├── cc.go │ │ │ │ │ │ ├── const_cc_ge0.go │ │ │ │ │ │ ├── const_cc_geu.go │ │ │ │ │ │ ├── const_cc_zero.go │ │ │ │ │ │ ├── count_nz_cc.go │ │ │ │ │ │ ├── div_cc.go │ │ │ │ │ │ ├── div_nz_cc.go │ │ │ │ │ │ ├── ext_sub_set_cc.go │ │ │ │ │ │ ├── false_cc.go │ │ │ │ │ │ ├── imm_shift_nz_cc.go │ │ │ │ │ │ ├── log_nz_cc.go │ │ │ │ │ │ ├── log_set_cc.go │ │ │ │ │ │ ├── mul_nz_cc.go │ │ │ │ │ │ ├── no_cc.go │ │ │ │ │ │ ├── release_cc.go │ │ │ │ │ │ ├── shift_nz_cc.go │ │ │ │ │ │ ├── sub_nz_cc.go │ │ │ │ │ │ ├── sub_set_cc.go │ │ │ │ │ │ ├── true_cc.go │ │ │ │ │ │ └── true_false_cc.go │ │ │ │ │ ├── endian.go │ │ │ │ │ ├── exception.go │ │ │ │ │ ├── flag.go │ │ │ │ │ ├── instruction.go │ │ │ │ │ ├── op_code.go │ │ │ │ │ ├── reg_descriptor/ │ │ │ │ │ │ ├── gp_reg_descriptor.go │ │ │ │ │ │ ├── pair_reg_descriptor.go │ │ │ │ │ │ ├── sp_reg_descriptor.go │ │ │ │ │ │ └── src_reg_descriptor.go │ │ │ │ │ └── suffix.go │ │ │ │ ├── kernel.go │ │ │ │ ├── label.go │ │ │ │ ├── liveness.go │ │ │ │ ├── relocatable.go │ │ │ │ └── section.go │ │ │ ├── lex_job.go │ │ │ ├── lexer/ │ │ │ │ ├── keyword_factory.go │ │ │ │ ├── lexer.go │ │ │ │ ├── regex.go │ │ │ │ ├── regex_factory.go │ │ │ │ ├── token.go │ │ │ │ ├── token_stream.go │ │ │ │ └── tokenizer.go │ │ │ ├── linker.go │ │ │ ├── logic/ │ │ │ │ ├── instruction_assigner.go │ │ │ │ ├── label_assigner.go │ │ │ │ ├── linker_constant.go │ │ │ │ ├── linker_script.go │ │ │ │ ├── liveness_analyzer.go │ │ │ │ └── set_assigner.go │ │ │ ├── parse_job.go │ │ │ └── parser/ │ │ │ ├── ast.go │ │ │ ├── expr/ │ │ │ │ ├── binary_add_expr.go │ │ │ │ ├── binary_sub_expr.go │ │ │ │ ├── ci_op_code_expr.go │ │ │ │ ├── condition_expr.go │ │ │ │ ├── ddci_op_code_expr.go │ │ │ │ ├── dma_rri_op_code_expr.go │ │ │ │ ├── drdici_op_code_expr.go │ │ │ │ ├── endian_expr.go │ │ │ │ ├── expr.go │ │ │ │ ├── i_op_code_expr.go │ │ │ │ ├── jump_op_code_expr.go │ │ │ │ ├── load_op_code_expr.go │ │ │ │ ├── negative_number_expr.go │ │ │ │ ├── primary_expr.go │ │ │ │ ├── program_counter_expr.go │ │ │ │ ├── r_op_code_expr.go │ │ │ │ ├── rici_op_code_expr.go │ │ │ │ ├── rr_op_code_expr.go │ │ │ │ ├── rri_op_code_expr.go │ │ │ │ ├── rrri_op_code_expr.go │ │ │ │ ├── section_name_expr.go │ │ │ │ ├── section_type_expr.go │ │ │ │ ├── src_reg_expr.go │ │ │ │ ├── store_op_code_expr.go │ │ │ │ ├── suffix_expr.go │ │ │ │ └── symbol_type.go │ │ │ ├── parser.go │ │ │ ├── rule.go │ │ │ ├── stack.go │ │ │ ├── stack_item.go │ │ │ ├── stmt/ │ │ │ │ ├── directive/ │ │ │ │ │ ├── addrsig_stmt.go │ │ │ │ │ ├── addrsig_sym_stmt.go │ │ │ │ │ ├── ascii_stmt.go │ │ │ │ │ ├── asciz_stmt.go │ │ │ │ │ ├── byte_stmt.go │ │ │ │ │ ├── cfi_def_cfa_offset_stmt.go │ │ │ │ │ ├── cfi_endproc.go │ │ │ │ │ ├── cfi_offset_stmt.go │ │ │ │ │ ├── cfi_sections_stmt.go │ │ │ │ │ ├── cfi_startproc_stmt.go │ │ │ │ │ ├── file_number_stmt.go │ │ │ │ │ ├── file_string_stmt.go │ │ │ │ │ ├── global_stmt.go │ │ │ │ │ ├── loc_is_stmt_stmt.go │ │ │ │ │ ├── loc_number_stmt.go │ │ │ │ │ ├── loc_prologue_end_stmt.go │ │ │ │ │ ├── long_program_counter.go │ │ │ │ │ ├── long_section_name_stmt.go │ │ │ │ │ ├── p2_align_stmt.go │ │ │ │ │ ├── quad_stmt.go │ │ │ │ │ ├── section_identifier_number_stmt.go │ │ │ │ │ ├── section_identifier_stmt.go │ │ │ │ │ ├── section_stack_sizes_stmt.go │ │ │ │ │ ├── section_string_number_stmt.go │ │ │ │ │ ├── section_string_stmt.go │ │ │ │ │ ├── set_stmt.go │ │ │ │ │ ├── short_stmt.go │ │ │ │ │ ├── size_stmt.go │ │ │ │ │ ├── text_stmt.go │ │ │ │ │ ├── type_stmt.go │ │ │ │ │ ├── weak_stmt.go │ │ │ │ │ ├── zero_double_number_stmt.go │ │ │ │ │ └── zero_single_number_stmt.go │ │ │ │ ├── instruction/ │ │ │ │ │ ├── ci_stmt.go │ │ │ │ │ ├── ddci_stmt.go │ │ │ │ │ ├── dma_rri_stmt.go │ │ │ │ │ ├── drdici_stmt.go │ │ │ │ │ ├── edri_stmt.go │ │ │ │ │ ├── erid_stmt.go │ │ │ │ │ ├── erii_stmt.go │ │ │ │ │ ├── erir_stmt.go │ │ │ │ │ ├── erri_stmt.go │ │ │ │ │ ├── i_stmt.go │ │ │ │ │ ├── nop_stmt.go │ │ │ │ │ ├── r_stmt.go │ │ │ │ │ ├── rci_stmt.go │ │ │ │ │ ├── rici_stmt.go │ │ │ │ │ ├── rir_stmt.go │ │ │ │ │ ├── rirc_stmt.go │ │ │ │ │ ├── rirci_stmt.go │ │ │ │ │ ├── rr_stmt.go │ │ │ │ │ ├── rrc_stmt.go │ │ │ │ │ ├── rrci_stmt.go │ │ │ │ │ ├── rri_stmt.go │ │ │ │ │ ├── rric_stmt.go │ │ │ │ │ ├── rrici_stmt.go │ │ │ │ │ ├── rrr_stmt.go │ │ │ │ │ ├── rrrc_stmt.go │ │ │ │ │ ├── rrrci_stmt.go │ │ │ │ │ ├── rrri_stmt.go │ │ │ │ │ ├── rrrici_stmt.go │ │ │ │ │ ├── s_erri_stmt.go │ │ │ │ │ ├── s_r_stmt.go │ │ │ │ │ ├── s_rci_stmt.go │ │ │ │ │ ├── s_rirc_stmt.go │ │ │ │ │ ├── s_rirci_stmt.go │ │ │ │ │ ├── s_rr_stmt.go │ │ │ │ │ ├── s_rrc_stmt.go │ │ │ │ │ ├── s_rrci_stmt.go │ │ │ │ │ ├── s_rri_stmt.go │ │ │ │ │ ├── s_rric_stmt.go │ │ │ │ │ ├── s_rrici_stmt.go │ │ │ │ │ ├── s_rrr_stmt.go │ │ │ │ │ ├── s_rrrc_stmt.go │ │ │ │ │ ├── s_rrrci_stmt.go │ │ │ │ │ ├── s_rrri_stmt.go │ │ │ │ │ └── s_rrrici_stmt.go │ │ │ │ ├── label_stmt.go │ │ │ │ ├── stmt.go │ │ │ │ └── sugar/ │ │ │ │ ├── bkp_stmt.go │ │ │ │ ├── boot_ri_stmt.go │ │ │ │ ├── call_ri_stmt.go │ │ │ │ ├── call_rr_stmt.go │ │ │ │ ├── div_step_drdi_stmt.go │ │ │ │ ├── jeq_rii_stmt.go │ │ │ │ ├── jeq_rri_stmt.go │ │ │ │ ├── jnz_ri_stmt.go │ │ │ │ ├── jump_i_stmt.go │ │ │ │ ├── jump_r_stmt.go │ │ │ │ ├── lbs_rri_stmt.go │ │ │ │ ├── lbs_s_rri_stmt.go │ │ │ │ ├── ld_dri_stmt.go │ │ │ │ ├── movd_dd_stmt.go │ │ │ │ ├── move_ri_stmt.go │ │ │ │ ├── move_rici_stmt.go │ │ │ │ ├── move_s_ri_stmt.go │ │ │ │ ├── move_s_rici_stmt.go │ │ │ │ ├── sb_id_ri_stmt.go │ │ │ │ ├── sb_id_rii_stmt.go │ │ │ │ ├── sb_rir_stmt.go │ │ │ │ ├── sd_rid_stmt.go │ │ │ │ ├── stop_stmt.go │ │ │ │ └── time_cfg_r_stmt.go │ │ │ ├── table.go │ │ │ └── walker.go │ │ └── simulator/ │ │ ├── channel/ │ │ │ ├── channel.go │ │ │ ├── channel_command.go │ │ │ └── channel_command_q.go │ │ ├── dpu/ │ │ │ ├── control_interface.go │ │ │ ├── dpu.go │ │ │ ├── dram/ │ │ │ │ ├── dma_command.go │ │ │ │ ├── dma_command_q.go │ │ │ │ ├── memory_command.go │ │ │ │ ├── memory_command_q.go │ │ │ │ ├── memory_controller.go │ │ │ │ ├── memory_scheduler.go │ │ │ │ ├── mram.go │ │ │ │ ├── row_buffer.go │ │ │ │ └── wordline.go │ │ │ ├── logic/ │ │ │ │ ├── alu.go │ │ │ │ ├── cycle_rule.go │ │ │ │ ├── dma.go │ │ │ │ ├── instruction_q.go │ │ │ │ ├── logic.go │ │ │ │ ├── operand_collector.go │ │ │ │ ├── pipeline.go │ │ │ │ ├── reg_set.go │ │ │ │ ├── thread.go │ │ │ │ ├── thread_q.go │ │ │ │ └── thread_scheduler.go │ │ │ ├── reg/ │ │ │ │ ├── condition_reg.go │ │ │ │ ├── exception_reg.go │ │ │ │ ├── flag_reg.go │ │ │ │ ├── gp_reg.go │ │ │ │ ├── pc_reg.go │ │ │ │ ├── reg_file.go │ │ │ │ └── sp_reg.go │ │ │ └── sram/ │ │ │ ├── atomic.go │ │ │ ├── iram.go │ │ │ ├── lock.go │ │ │ └── wram.go │ │ └── rank/ │ │ ├── rank.go │ │ ├── rank_command.go │ │ └── rank_command_q.go │ ├── encoding/ │ │ ├── ascii_encoder.go │ │ └── byte_stream.go │ ├── host/ │ │ ├── abi/ │ │ │ ├── binary.go │ │ │ ├── bytecode.go │ │ │ ├── label.go │ │ │ ├── op_code.go │ │ │ └── relocatable.go │ │ ├── interpreter/ │ │ │ ├── codegen/ │ │ │ │ ├── codegen.go │ │ │ │ └── type_system/ │ │ │ │ ├── method.go │ │ │ │ ├── symbol.go │ │ │ │ └── type_system.go │ │ │ ├── interpreter.go │ │ │ ├── lexer/ │ │ │ │ ├── keyword_factory.go │ │ │ │ ├── lexer.go │ │ │ │ ├── regex.go │ │ │ │ ├── regex_factory.go │ │ │ │ ├── token.go │ │ │ │ ├── token_stream.go │ │ │ │ └── tokenizer.go │ │ │ └── parser/ │ │ │ ├── ast.go │ │ │ ├── decl/ │ │ │ │ ├── decl.go │ │ │ │ ├── func_decl.go │ │ │ │ ├── func_def.go │ │ │ │ └── struct_def.go │ │ │ ├── directive/ │ │ │ │ ├── define_directive.go │ │ │ │ ├── directive.go │ │ │ │ └── include_directive.go │ │ │ ├── expr/ │ │ │ │ ├── additive_expr.go │ │ │ │ ├── arg_list.go │ │ │ │ ├── assignment_expr.go │ │ │ │ ├── bitwise_and_expr.go │ │ │ │ ├── bitwise_or_expr.go │ │ │ │ ├── bitwise_xor_expr.go │ │ │ │ ├── conditional_expr.go │ │ │ │ ├── equality_expr.go │ │ │ │ ├── expr.go │ │ │ │ ├── logical_and_expr.go │ │ │ │ ├── logical_or_expr.go │ │ │ │ ├── multiplicative_expr.go │ │ │ │ ├── postfix_expr.go │ │ │ │ ├── primary_expr.go │ │ │ │ ├── relational_expr.go │ │ │ │ ├── shift_expr.go │ │ │ │ └── unary_expr.go │ │ │ ├── param_list/ │ │ │ │ ├── param.go │ │ │ │ └── param_list.go │ │ │ ├── parser.go │ │ │ ├── rule.go │ │ │ ├── stack.go │ │ │ ├── stack_item.go │ │ │ ├── stmt/ │ │ │ │ ├── block_stmt.go │ │ │ │ ├── break_stmt.go │ │ │ │ ├── continue_stmt.go │ │ │ │ ├── dpu_foreach_stmt.go │ │ │ │ ├── empty_stmt.go │ │ │ │ ├── expr_stmt.go │ │ │ │ ├── for_stmt.go │ │ │ │ ├── if_stmt.go │ │ │ │ ├── return_stmt.go │ │ │ │ ├── stmt.go │ │ │ │ ├── var_decl_init_stmt.go │ │ │ │ ├── var_decl_stmt.go │ │ │ │ └── while_stmt.go │ │ │ ├── table.go │ │ │ └── type_specifier/ │ │ │ └── type_specifier.go │ │ └── vm/ │ │ ├── arena/ │ │ │ ├── arena.go │ │ │ ├── garbage_collector.go │ │ │ ├── memory.go │ │ │ └── pool.go │ │ ├── bank_cycle_job.go │ │ ├── base/ │ │ │ └── object.go │ │ ├── dpu_compute_cycle_job.go │ │ ├── dpu_cycle_job.go │ │ ├── dpu_load_job.go │ │ ├── dram/ │ │ │ ├── bank/ │ │ │ │ ├── array.go │ │ │ │ ├── bank.go │ │ │ │ ├── dma_command.go │ │ │ │ ├── dma_command_q.go │ │ │ │ ├── memory_command.go │ │ │ │ ├── memory_command_q.go │ │ │ │ ├── row_buffer.go │ │ │ │ ├── segment.go │ │ │ │ ├── transfer_command.go │ │ │ │ ├── transfer_command_q.go │ │ │ │ └── wordline.go │ │ │ ├── channel/ │ │ │ │ ├── channel.go │ │ │ │ ├── channel_command.go │ │ │ │ └── channel_command_q.go │ │ │ ├── memory_controller.go │ │ │ ├── memory_mapping.go │ │ │ ├── memory_scheduler.go │ │ │ └── rank/ │ │ │ ├── rank.go │ │ │ ├── rank_command.go │ │ │ └── rank_command_q.go │ │ ├── frame/ │ │ │ ├── frame.go │ │ │ └── frame_chain.go │ │ ├── pc/ │ │ │ └── pc.go │ │ ├── stack/ │ │ │ ├── return_stack.go │ │ │ ├── stack.go │ │ │ └── stack_item.go │ │ ├── symbol/ │ │ │ ├── scope.go │ │ │ ├── scope_chain.go │ │ │ └── symbol.go │ │ ├── type_system/ │ │ │ ├── field.go │ │ │ ├── registry.go │ │ │ ├── skeleton.go │ │ │ └── type_variable.go │ │ └── virtual_machine.go │ ├── main.go │ ├── misc/ │ │ ├── command_line_option.go │ │ ├── command_line_parser.go │ │ ├── command_line_validator.go │ │ ├── config_loader.go │ │ ├── config_validator.go │ │ ├── file_dumper.go │ │ ├── file_scanner.go │ │ └── stat_factory.go │ ├── program/ │ │ ├── app.go │ │ └── task.go │ └── system/ │ └── system.go ├── python_cpp/ │ ├── README.md │ ├── uPIMulator_backend/ │ │ ├── CMakeLists.txt │ │ ├── script/ │ │ │ ├── build.sh │ │ │ ├── format.sh │ │ │ ├── run.sh │ │ │ └── run_serial.sh │ │ └── src/ │ │ ├── CMakeLists.txt │ │ ├── abi/ │ │ │ ├── cc/ │ │ │ │ ├── _base_cc.cc │ │ │ │ ├── _base_cc.h │ │ │ │ ├── acquire_cc.h │ │ │ │ ├── add_nz_cc.h │ │ │ │ ├── boot_cc.h │ │ │ │ ├── const_cc_ge0.h │ │ │ │ ├── const_cc_geu.h │ │ │ │ ├── const_cc_zero.h │ │ │ │ ├── count_nz_cc.h │ │ │ │ ├── div_cc.h │ │ │ │ ├── div_nz_cc.h │ │ │ │ ├── ext_sub_set_cc.h │ │ │ │ ├── false_cc.h │ │ │ │ ├── imm_shift_nz_cc.h │ │ │ │ ├── log_nz_cc.h │ │ │ │ ├── log_set_cc.h │ │ │ │ ├── mul_nz_cc.h │ │ │ │ ├── no_cc.h │ │ │ │ ├── release_cc.h │ │ │ │ ├── shift_nz_cc.h │ │ │ │ ├── sub_nz_cc.h │ │ │ │ ├── sub_set_cc.h │ │ │ │ ├── true_cc.h │ │ │ │ └── true_false_cc.h │ │ │ ├── instruction/ │ │ │ │ ├── instruction.cc │ │ │ │ ├── instruction.h │ │ │ │ ├── op_code.h │ │ │ │ └── suffix.h │ │ │ ├── isa/ │ │ │ │ ├── condition.h │ │ │ │ ├── endian.h │ │ │ │ ├── exception.h │ │ │ │ └── flag.h │ │ │ ├── reg/ │ │ │ │ ├── gp_reg.h │ │ │ │ ├── pair_reg.cc │ │ │ │ ├── pair_reg.h │ │ │ │ ├── sp_reg.h │ │ │ │ ├── src_reg.cc │ │ │ │ └── src_reg.h │ │ │ └── word/ │ │ │ ├── _base_word.cc │ │ │ ├── _base_word.h │ │ │ ├── data_address_word.h │ │ │ ├── data_word.h │ │ │ ├── immediate.h │ │ │ ├── instruction_address_word.h │ │ │ ├── instruction_word.h │ │ │ └── representation.h │ │ ├── converter/ │ │ │ ├── condition_converter.cc │ │ │ ├── condition_converter.h │ │ │ ├── endian_converter.cc │ │ │ ├── endian_converter.h │ │ │ ├── flag_converter.cc │ │ │ ├── flag_converter.h │ │ │ ├── instruction_converter.cc │ │ │ ├── instruction_converter.h │ │ │ ├── op_code_converter.cc │ │ │ ├── op_code_converter.h │ │ │ ├── reg_converter.cc │ │ │ ├── reg_converter.h │ │ │ ├── reg_file_converter.cc │ │ │ ├── reg_file_converter.h │ │ │ ├── suffix_converter.cc │ │ │ └── suffix_converter.h │ │ ├── encoder/ │ │ │ ├── byte.h │ │ │ ├── byte_stream.cc │ │ │ ├── byte_stream.h │ │ │ ├── instruction_encoder.cc │ │ │ └── instruction_encoder.h │ │ ├── initializer/ │ │ │ ├── int_initializer.cc │ │ │ ├── int_initializer.h │ │ │ ├── str_initializer.h │ │ │ └── str_initialzier.cc │ │ ├── main.cc │ │ ├── main.h │ │ ├── simulator/ │ │ │ ├── basic/ │ │ │ │ ├── queue.h │ │ │ │ └── timer_queue.h │ │ │ ├── cpu/ │ │ │ │ ├── cpu.cc │ │ │ │ ├── cpu.h │ │ │ │ ├── fini_thread.cc │ │ │ │ ├── fini_thread.h │ │ │ │ ├── init_thread.cc │ │ │ │ ├── init_thread.h │ │ │ │ ├── sched_thread.cc │ │ │ │ ├── sched_thread.h │ │ │ │ ├── thread.cc │ │ │ │ └── thread.h │ │ │ ├── dpu/ │ │ │ │ ├── alu.cc │ │ │ │ ├── alu.h │ │ │ │ ├── cycle_rule.cc │ │ │ │ ├── cycle_rule.h │ │ │ │ ├── dma.cc │ │ │ │ ├── dma.h │ │ │ │ ├── dma_command.cc │ │ │ │ ├── dma_command.h │ │ │ │ ├── dpu.cc │ │ │ │ ├── dpu.h │ │ │ │ ├── logic.cc │ │ │ │ ├── logic.h │ │ │ │ ├── operand_collector.cc │ │ │ │ ├── operand_collector.h │ │ │ │ ├── pipeline.cc │ │ │ │ ├── pipeline.h │ │ │ │ ├── revolver_scheduler.cc │ │ │ │ ├── revolver_scheduler.h │ │ │ │ ├── thread.cc │ │ │ │ └── thread.h │ │ │ ├── dram/ │ │ │ │ ├── fifo_scheduler.cc │ │ │ │ ├── fifo_scheduler.h │ │ │ │ ├── frfcfs_scheduler.cc │ │ │ │ ├── frfcfs_scheduler.h │ │ │ │ ├── memory_command.cc │ │ │ │ ├── memory_command.h │ │ │ │ ├── memory_controller.cc │ │ │ │ ├── memory_controller.h │ │ │ │ ├── mram.cc │ │ │ │ ├── mram.h │ │ │ │ ├── row_buffer.cc │ │ │ │ ├── row_buffer.h │ │ │ │ ├── scheduler.cc │ │ │ │ ├── scheduler.h │ │ │ │ ├── wordline.cc │ │ │ │ └── wordline.h │ │ │ ├── rank/ │ │ │ │ ├── rank.cc │ │ │ │ ├── rank.h │ │ │ │ └── rank_message.h │ │ │ ├── reg/ │ │ │ │ ├── condition_reg.cc │ │ │ │ ├── condition_reg.h │ │ │ │ ├── exception_reg.h │ │ │ │ ├── flag_reg.h │ │ │ │ ├── gp_reg.cc │ │ │ │ ├── gp_reg.h │ │ │ │ ├── pc_reg.h │ │ │ │ ├── reg_file.cc │ │ │ │ ├── reg_file.h │ │ │ │ ├── sp_reg.cc │ │ │ │ └── sp_reg.h │ │ │ ├── sram/ │ │ │ │ ├── atomic.cc │ │ │ │ ├── atomic.h │ │ │ │ ├── iram.cc │ │ │ │ ├── iram.h │ │ │ │ ├── lock.cc │ │ │ │ ├── lock.h │ │ │ │ ├── wram.cc │ │ │ │ └── wram.h │ │ │ ├── system.cc │ │ │ └── system.h │ │ └── util/ │ │ ├── argument_parser.cc │ │ ├── argument_parser.h │ │ ├── config_loader.h │ │ ├── stat_factory.cc │ │ └── stat_factory.h │ └── uPIMulator_frontend/ │ ├── .flake8 │ ├── .hadolint.yaml │ ├── .isort.cfg │ ├── .markdownlint.yaml │ ├── .shellcheckrc │ ├── benchmark/ │ │ ├── Arithmetic-Throughput/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── BFS/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app.cu │ │ │ ├── data/ │ │ │ │ └── loc-gowalla_edges.txt │ │ │ ├── dpu/ │ │ │ │ ├── dpu-utils.h │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ ├── app.c │ │ │ │ └── mram-management.h │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── graph.h │ │ │ ├── params.h │ │ │ ├── timer.h │ │ │ └── utils.h │ │ ├── BS/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── bs_omp.c │ │ │ │ │ └── timer.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── binary_search.cu │ │ │ │ ├── binary_search.h │ │ │ │ ├── cpu_lib.py │ │ │ │ ├── cu_lib_import.py │ │ │ │ └── run.py │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── CPU-DPU/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── GEMV/ │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── gemv_openmp.c │ │ │ │ │ └── gemv_utils.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── gemv.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-L/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── HST-S/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── input/ │ │ │ │ │ └── image_VanHateren.iml │ │ │ │ ├── kernel.cpp │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── partitioner.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── input/ │ │ │ │ └── image_VanHateren.iml │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── MLP/ │ │ │ ├── Makefile │ │ │ ├── _BL_10.conf │ │ │ ├── _NR_TASKLETS_10_BL_10.conf │ │ │ ├── _NR_TASKLETS_11_BL_10.conf │ │ │ ├── _NR_TASKLETS_12_BL_10.conf │ │ │ ├── _NR_TASKLETS_13_BL_10.conf │ │ │ ├── _NR_TASKLETS_14_BL_10.conf │ │ │ ├── _NR_TASKLETS_15_BL_10.conf │ │ │ ├── _NR_TASKLETS_16 │ │ │ ├── _NR_TASKLETS_16_BL_10.conf │ │ │ ├── _NR_TASKLETS_17_BL_10.conf │ │ │ ├── _NR_TASKLETS_18_BL_10.conf │ │ │ ├── _NR_TASKLETS_19_BL_10.conf │ │ │ ├── _NR_TASKLETS_1_BL_10.conf │ │ │ ├── _NR_TASKLETS_20_BL_10.conf │ │ │ ├── _NR_TASKLETS_21_BL_10.conf │ │ │ ├── _NR_TASKLETS_22_BL_10.conf │ │ │ ├── _NR_TASKLETS_23_BL_10.conf │ │ │ ├── _NR_TASKLETS_24_BL_10.conf │ │ │ ├── _NR_TASKLETS_2_BL_10.conf │ │ │ ├── _NR_TASKLETS_3_BL_10.conf │ │ │ ├── _NR_TASKLETS_4_BL_10.conf │ │ │ ├── _NR_TASKLETS_5_BL_10.conf │ │ │ ├── _NR_TASKLETS_6_BL_10.conf │ │ │ ├── _NR_TASKLETS_7_BL_10.conf │ │ │ ├── _NR_TASKLETS_8_BL_10.conf │ │ │ ├── _NR_TASKLETS_9_BL_10.conf │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── mlp_openmp.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── mlp.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── MRAM-Latency/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── copy.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── NW/ │ │ │ ├── .conf │ │ │ ├── Makefile │ │ │ ├── _NR_TASKLETS_10_BL_1024 │ │ │ ├── _NR_TASKLETS_11_BL_1024 │ │ │ ├── _NR_TASKLETS_12_BL_1024 │ │ │ ├── _NR_TASKLETS_13_BL_1024 │ │ │ ├── _NR_TASKLETS_14_BL_1024 │ │ │ ├── _NR_TASKLETS_15_BL_1024 │ │ │ ├── _NR_TASKLETS_16_BL_1024 │ │ │ ├── _NR_TASKLETS_17_BL_1024 │ │ │ ├── _NR_TASKLETS_18_BL_1024 │ │ │ ├── _NR_TASKLETS_19_BL_1024 │ │ │ ├── _NR_TASKLETS_1_BL_1024 │ │ │ ├── _NR_TASKLETS_20_BL_1024 │ │ │ ├── _NR_TASKLETS_21_BL_1024 │ │ │ ├── _NR_TASKLETS_22_BL_1024 │ │ │ ├── _NR_TASKLETS_23_BL_1024 │ │ │ ├── _NR_TASKLETS_24_BL_1024 │ │ │ ├── _NR_TASKLETS_2_BL_1024 │ │ │ ├── _NR_TASKLETS_3_BL_1024 │ │ │ ├── _NR_TASKLETS_4_BL_1024 │ │ │ ├── _NR_TASKLETS_5_BL_1024 │ │ │ ├── _NR_TASKLETS_6_BL_1024 │ │ │ ├── _NR_TASKLETS_7_BL_1024 │ │ │ ├── _NR_TASKLETS_8_BL_1024 │ │ │ ├── _NR_TASKLETS_9_BL_1024 │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── needle.cpp │ │ │ │ │ ├── run │ │ │ │ │ └── run_offload │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── Makefile_nvidia │ │ │ │ ├── README │ │ │ │ ├── common/ │ │ │ │ │ ├── common.mk │ │ │ │ │ └── make.config │ │ │ │ ├── needle.cu │ │ │ │ ├── needle.h │ │ │ │ ├── needle_kernel.cu │ │ │ │ ├── run │ │ │ │ └── timing.h │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── Operational-Intensity/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── RED/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── Random-GUPS/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── gups.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-RSS/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app_baseline.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SCAN-SSA/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SEL/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── select.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── STREAM/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ ├── add.c │ │ │ │ ├── copy.c │ │ │ │ ├── copyw.c │ │ │ │ ├── scale.c │ │ │ │ └── triad.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── STRIDED/ │ │ │ ├── Makefile │ │ │ ├── dpu/ │ │ │ │ └── strided.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ ├── run.sh │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── cyclecount.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── SpMV/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── app.cu │ │ │ ├── data/ │ │ │ │ ├── bcsstk30.mtx │ │ │ │ └── generate/ │ │ │ │ ├── Makefile │ │ │ │ ├── generate.sh │ │ │ │ └── replicate.c │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ ├── app.c │ │ │ │ └── mram-management.h │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── matrix.h │ │ │ ├── params.h │ │ │ ├── timer.h │ │ │ └── utils.h │ │ ├── TRNS/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── kernel.cpp │ │ │ │ │ ├── kernel.h │ │ │ │ │ ├── main.cpp │ │ │ │ │ └── support/ │ │ │ │ │ ├── common.h │ │ │ │ │ ├── setup.h │ │ │ │ │ ├── timer.h │ │ │ │ │ └── verify.h │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── kernel.cu │ │ │ │ ├── kernel.h │ │ │ │ ├── main.cpp │ │ │ │ └── support/ │ │ │ │ ├── common.h │ │ │ │ ├── cuda-setup.h │ │ │ │ ├── timer.h │ │ │ │ └── verify.h │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── TS/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ ├── inputs/ │ │ │ │ │ │ └── randomlist33M.txt │ │ │ │ │ ├── launch.sh │ │ │ │ │ ├── mprofile.h │ │ │ │ │ ├── streamp_openmp.cpp │ │ │ │ │ └── tools.cpp │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── STREAMP.cu │ │ │ │ ├── inputs/ │ │ │ │ │ └── randomlist33M.txt │ │ │ │ ├── launch.sh │ │ │ │ └── randlist.py │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── UNI/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ ├── ds.h │ │ │ │ ├── kernel.cu │ │ │ │ └── unique.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ ├── VA/ │ │ │ ├── Makefile │ │ │ ├── baselines/ │ │ │ │ ├── cpu/ │ │ │ │ │ ├── Makefile │ │ │ │ │ ├── README │ │ │ │ │ └── app_baseline.c │ │ │ │ └── gpu/ │ │ │ │ ├── Makefile │ │ │ │ ├── README │ │ │ │ └── vec_add.cu │ │ │ ├── dpu/ │ │ │ │ └── task.c │ │ │ ├── host/ │ │ │ │ └── app.c │ │ │ └── support/ │ │ │ ├── common.h │ │ │ ├── params.h │ │ │ └── timer.h │ │ └── WRAM/ │ │ ├── Makefile │ │ ├── dpu/ │ │ │ └── task.c │ │ ├── host/ │ │ │ └── app.c │ │ ├── run.sh │ │ └── support/ │ │ ├── common.h │ │ ├── cyclecount.h │ │ ├── params.h │ │ └── timer.h │ ├── docker/ │ │ ├── compiler.dockerfile │ │ └── parser.dockerfile │ ├── pyproject.toml │ ├── requirements.txt │ ├── sdk/ │ │ ├── misc/ │ │ │ ├── accessMramFromDpu.c │ │ │ ├── coreDump.c │ │ │ ├── crt0.c │ │ │ ├── dpu.lds │ │ │ ├── internalStateReset.c │ │ │ ├── linkerScript.lds │ │ │ ├── restoreRegisters.c │ │ │ └── restore_carry_and_zero_flag.h │ │ ├── stdlib/ │ │ │ ├── abort.c │ │ │ ├── assert.h │ │ │ ├── atoi.c │ │ │ ├── atol.c │ │ │ ├── ctype.h │ │ │ ├── errno.c │ │ │ ├── errno.h │ │ │ ├── exit.c │ │ │ ├── inttypes.h │ │ │ ├── iso646.h │ │ │ ├── limits.h │ │ │ ├── memchr.c │ │ │ ├── memcmp.c │ │ │ ├── memcpy.c │ │ │ ├── memmove.c │ │ │ ├── memmram_utils.h │ │ │ ├── memset.c │ │ │ ├── stdalign.h │ │ │ ├── stdarg.h │ │ │ ├── stdbool.h │ │ │ ├── stddef.h │ │ │ ├── stdint.h │ │ │ ├── stdio.c │ │ │ ├── stdio.h │ │ │ ├── stdlib.h │ │ │ ├── stdnoreturn.h │ │ │ ├── stpcpy.c │ │ │ ├── stpncpy.c │ │ │ ├── strcat.c │ │ │ ├── strchr.c │ │ │ ├── strcmp.c │ │ │ ├── strcpy.c │ │ │ ├── strcspn.c │ │ │ ├── strdup.c │ │ │ ├── strerror.c │ │ │ ├── string.h │ │ │ ├── strlen.c │ │ │ ├── strlwr.c │ │ │ ├── strncat.c │ │ │ ├── strncmp.c │ │ │ ├── strncpy.c │ │ │ ├── strndup.c │ │ │ ├── strnlen.c │ │ │ ├── strpbrk.c │ │ │ ├── strrchr.c │ │ │ ├── strrev.c │ │ │ ├── strsep.c │ │ │ ├── strspn.c │ │ │ ├── strstr.c │ │ │ ├── strtok_r.c │ │ │ ├── strtol.c │ │ │ └── strupr.c │ │ └── syslib/ │ │ ├── absvdi2.c │ │ ├── absvsi2.c │ │ ├── adddf3.c │ │ ├── addsf3.c │ │ ├── addvdi3.c │ │ ├── addvsi3.c │ │ ├── alloc.c │ │ ├── alloc.h │ │ ├── ashldi3.c │ │ ├── ashrdi3.c │ │ ├── atomic_bit.h │ │ ├── atomics.c │ │ ├── attributes.h │ │ ├── barrier.c │ │ ├── barrier.h │ │ ├── bswapdi2.c │ │ ├── bswapsi2.c │ │ ├── buddy_alloc.c │ │ ├── buddy_alloc.h │ │ ├── buddy_realloc.c │ │ ├── built_ins.h │ │ ├── clzdi2.c │ │ ├── clzsi2.c │ │ ├── cmpdi2.c │ │ ├── comparedf2.c │ │ ├── comparesf2.c │ │ ├── ctzdi2.c │ │ ├── ctzsi2.c │ │ ├── defs.c │ │ ├── defs.h │ │ ├── devprivate.h │ │ ├── div32.c │ │ ├── divdf3.c │ │ ├── divdi3.c │ │ ├── divmodsi4.c │ │ ├── divsf3.c │ │ ├── divsi3.c │ │ ├── dpuconst.h │ │ ├── dpufault.h │ │ ├── dpuruntime.h │ │ ├── extendhfsf2.c │ │ ├── extendsfdf2.c │ │ ├── ffsdi2.c │ │ ├── ffssi2.c │ │ ├── ffsti2.c │ │ ├── fixdfdi.c │ │ ├── fixdfsi.c │ │ ├── fixsfdi.c │ │ ├── fixsfsi.c │ │ ├── fixunsdfdi.c │ │ ├── fixunsdfsi.c │ │ ├── fixunssfdi.c │ │ ├── fixunssfsi.c │ │ ├── float.h │ │ ├── floatdidf.c │ │ ├── floatdisf.c │ │ ├── floatsidf.c │ │ ├── floatsisf.c │ │ ├── floatundidf.c │ │ ├── floatundisf.c │ │ ├── floatunsidf.c │ │ ├── floatunsisf.c │ │ ├── fp_add_impl.inc │ │ ├── fp_extend.h │ │ ├── fp_extend_impl.inc │ │ ├── fp_fixint_impl.inc │ │ ├── fp_fixuint_impl.inc │ │ ├── fp_lib.h │ │ ├── fp_mul_impl.inc │ │ ├── fp_trunc.h │ │ ├── fp_trunc_impl.inc │ │ ├── fsb_allocator.c │ │ ├── fsb_allocator.h │ │ ├── handshake.c │ │ ├── handshake.h │ │ ├── int_endianness.h │ │ ├── int_lib.h │ │ ├── int_math.h │ │ ├── int_types.h │ │ ├── int_util.c │ │ ├── int_util.h │ │ ├── listener.c │ │ ├── lshrdi3.c │ │ ├── macro_utils.h │ │ ├── mcount.c │ │ ├── moddi3.c │ │ ├── modsi3.c │ │ ├── mram.h │ │ ├── mul32.c │ │ ├── mul64.c │ │ ├── muldc3.c │ │ ├── muldf3.c │ │ ├── mulodi4.c │ │ ├── mulosi4.c │ │ ├── mulsf3.c │ │ ├── mulvdi3.c │ │ ├── mulvsi3.c │ │ ├── mutex.h │ │ ├── negdf2.c │ │ ├── negdi2.c │ │ ├── negsf2.c │ │ ├── negvdi2.c │ │ ├── negvsi2.c │ │ ├── paritydi2.c │ │ ├── paritysi2.c │ │ ├── perfcounter.c │ │ ├── perfcounter.h │ │ ├── popcountdi2.c │ │ ├── popcountsi2.c │ │ ├── powidf2.c │ │ ├── powisf2.c │ │ ├── profiling.c │ │ ├── profiling.h │ │ ├── profiling_internals.h │ │ ├── sem.c │ │ ├── sem.h │ │ ├── seqread.h │ │ ├── seqread.inc │ │ ├── seqread1024.c │ │ ├── seqread128.c │ │ ├── seqread256.c │ │ ├── seqread32.c │ │ ├── seqread512.c │ │ ├── seqread64.c │ │ ├── soft_cache.c │ │ ├── soft_cache.h │ │ ├── subdf3.c │ │ ├── subsf3.c │ │ ├── subvdi3.c │ │ ├── subvsi3.c │ │ ├── sysdef.h │ │ ├── truncdfhf2.c │ │ ├── truncdfsf2.c │ │ ├── truncsfhf2.c │ │ ├── ucmpdi2.c │ │ ├── udiv64.c │ │ ├── udivdi3.c │ │ ├── udivmodsi4.c │ │ ├── udivsi3.c │ │ ├── umoddi3.c │ │ ├── umodsi3.c │ │ └── waitqueue.c │ ├── src/ │ │ ├── abi/ │ │ │ ├── binary/ │ │ │ │ ├── executable.py │ │ │ │ ├── liveness.py │ │ │ │ └── relocatable.py │ │ │ ├── directive/ │ │ │ │ ├── ascii_directive.py │ │ │ │ ├── asciz_directive.py │ │ │ │ ├── byte_directive.py │ │ │ │ ├── long_directive.py │ │ │ │ ├── quad_directive.py │ │ │ │ ├── short_directive.py │ │ │ │ └── zero_directive.py │ │ │ ├── isa/ │ │ │ │ ├── cc/ │ │ │ │ │ ├── _base_cc.py │ │ │ │ │ ├── acquire_cc.py │ │ │ │ │ ├── add_nz_cc.py │ │ │ │ │ ├── boot_cc.py │ │ │ │ │ ├── const_cc_ge0.py │ │ │ │ │ ├── const_cc_geu.py │ │ │ │ │ ├── const_cc_zero.py │ │ │ │ │ ├── count_nz_cc.py │ │ │ │ │ ├── div_cc.py │ │ │ │ │ ├── div_nz_cc.py │ │ │ │ │ ├── ext_sub_set_cc.py │ │ │ │ │ ├── false_cc.py │ │ │ │ │ ├── imm_shift_nz_cc.py │ │ │ │ │ ├── log_nz_cc.py │ │ │ │ │ ├── log_set_cc.py │ │ │ │ │ ├── mul_nz_cc.py │ │ │ │ │ ├── no_cc.py │ │ │ │ │ ├── release_cc.py │ │ │ │ │ ├── shift_nz_cc.py │ │ │ │ │ ├── sub_nz_cc.py │ │ │ │ │ ├── sub_set_cc.py │ │ │ │ │ ├── true_cc.py │ │ │ │ │ └── true_false_cc.py │ │ │ │ ├── exception.py │ │ │ │ ├── flag.py │ │ │ │ ├── instruction/ │ │ │ │ │ ├── condition.py │ │ │ │ │ ├── endian.py │ │ │ │ │ ├── instruction.py │ │ │ │ │ ├── op_code.py │ │ │ │ │ └── suffix.py │ │ │ │ └── register/ │ │ │ │ ├── gp_register.py │ │ │ │ ├── pair_register.py │ │ │ │ └── sp_register.py │ │ │ ├── label/ │ │ │ │ ├── label.py │ │ │ │ └── symbol.py │ │ │ ├── section/ │ │ │ │ ├── section.py │ │ │ │ ├── section_flag.py │ │ │ │ ├── section_name.py │ │ │ │ └── section_type.py │ │ │ └── word/ │ │ │ ├── _base_word.py │ │ │ ├── data_address_word.py │ │ │ ├── data_word.py │ │ │ ├── double_data_word.py │ │ │ ├── immediate.py │ │ │ ├── instruction_address_word.py │ │ │ ├── instruction_word.py │ │ │ └── representation.py │ │ ├── assembler/ │ │ │ ├── assembler.py │ │ │ └── data_prep/ │ │ │ ├── bin.py │ │ │ ├── bs_data_prep.py │ │ │ ├── gemv_data_prep.py │ │ │ ├── hst_data_prep.py │ │ │ ├── mlp_data_prep.py │ │ │ ├── red_data_prep.py │ │ │ ├── scan_rss_data_prep.py │ │ │ ├── scan_ssa_data_prep.py │ │ │ ├── sel_data_prep.py │ │ │ ├── trns_data_prep.py │ │ │ ├── ts_data_prep.py │ │ │ ├── uni_data_prep.py │ │ │ └── va_data_prep.py │ │ ├── compiler/ │ │ │ └── compiler.py │ │ ├── converter/ │ │ │ ├── condition_converter.py │ │ │ ├── endian_converter.py │ │ │ ├── instruction_converter.py │ │ │ ├── op_code_converter.py │ │ │ ├── register_converter.py │ │ │ ├── section_flag_converter.py │ │ │ ├── section_name_converter.py │ │ │ ├── section_type_converter.py │ │ │ ├── suffix_converter.py │ │ │ └── symbol_converter.py │ │ ├── encoder/ │ │ │ ├── ascii_encoder.py │ │ │ ├── byte.py │ │ │ ├── directive_encoder.py │ │ │ └── instruction_encoder.py │ │ ├── initializer/ │ │ │ ├── directive_initializer.py │ │ │ ├── instruction_initializer.py │ │ │ ├── int_initializer.py │ │ │ └── str_initializer.py │ │ ├── iss/ │ │ │ ├── cpu/ │ │ │ │ ├── cpu.py │ │ │ │ ├── fini_thread.py │ │ │ │ ├── init_thread.py │ │ │ │ └── sched_thread.py │ │ │ ├── dpu/ │ │ │ │ ├── alu.py │ │ │ │ ├── decoder.py │ │ │ │ ├── dispatcher.py │ │ │ │ ├── dma.py │ │ │ │ ├── dpu.py │ │ │ │ ├── logic.py │ │ │ │ ├── scheduler.py │ │ │ │ └── thread.py │ │ │ ├── dram/ │ │ │ │ ├── mram.py │ │ │ │ ├── mram_command.py │ │ │ │ └── word.py │ │ │ ├── register/ │ │ │ │ ├── condition_register.py │ │ │ │ ├── exception_register.py │ │ │ │ ├── flag_register.py │ │ │ │ ├── gp_register.py │ │ │ │ ├── pc_register.py │ │ │ │ ├── register_file.py │ │ │ │ └── sp_register.py │ │ │ ├── sram/ │ │ │ │ ├── atomic.py │ │ │ │ ├── iram.py │ │ │ │ ├── lock.py │ │ │ │ └── wram.py │ │ │ └── system.py │ │ ├── linker_/ │ │ │ ├── linker.py │ │ │ ├── linker_script.py │ │ │ └── logic/ │ │ │ ├── instruction_assigner.py │ │ │ ├── label_assigner.py │ │ │ ├── liveness_analyzer.py │ │ │ └── set_assigner.py │ │ ├── main.py │ │ ├── parser_/ │ │ │ ├── grammar/ │ │ │ │ ├── .antlr/ │ │ │ │ │ ├── assembly.interp │ │ │ │ │ ├── assembly.tokens │ │ │ │ │ ├── assemblyLexer.interp │ │ │ │ │ ├── assemblyLexer.java │ │ │ │ │ ├── assemblyLexer.tokens │ │ │ │ │ └── assemblyParser.java │ │ │ │ ├── assembly.g4 │ │ │ │ ├── assembly.interp │ │ │ │ ├── assembly.tokens │ │ │ │ ├── assemblyLexer.interp │ │ │ │ ├── assemblyLexer.py │ │ │ │ ├── assemblyLexer.tokens │ │ │ │ ├── assemblyListener.py │ │ │ │ └── assemblyParser.py │ │ │ ├── grammar_generator.py │ │ │ └── parser.py │ │ └── util/ │ │ ├── config_loader.py │ │ ├── docker_client.py │ │ ├── param_loader.py │ │ └── path_collector.py │ └── test/ │ ├── abi/ │ │ ├── binary/ │ │ │ ├── executable_test.py │ │ │ └── liveness_test.py │ │ ├── directive/ │ │ │ ├── ascii_directive_test.py │ │ │ ├── asciz_directive_test.py │ │ │ ├── byte_directive_test.py │ │ │ ├── long_directive_test.py │ │ │ ├── quad_directive_test.py │ │ │ ├── short_directive_test.py │ │ │ └── zero_directive_test.py │ │ ├── isa/ │ │ │ └── register/ │ │ │ ├── gp_register_test.py │ │ │ └── pair_register_test.py │ │ ├── label/ │ │ │ └── label_test.py │ │ ├── section/ │ │ │ └── section_test.py │ │ └── word/ │ │ ├── immediate_test.py │ │ └── words_test.py │ ├── compiler/ │ │ └── compiler_test.py │ ├── encoder/ │ │ ├── ascii_encoder_test.py │ │ ├── directive_encoder_test.py │ │ └── instruction_encoder_test.py │ ├── iss/ │ │ ├── dpu/ │ │ │ ├── dma_test.py │ │ │ └── scheduler_test.py │ │ ├── dram/ │ │ │ └── mram_test.py │ │ ├── register/ │ │ │ └── register_file_test.py │ │ └── sram/ │ │ ├── atomic_test.py │ │ ├── iram_test.py │ │ └── wram_test.py │ ├── linker_/ │ │ └── linker_test.py │ ├── parser_/ │ │ ├── grammar_generator_test.py │ │ └── parser_test.py │ └── util/ │ └── config_loader_test.py └── tools/ ├── README.md ├── upmem_profiler/ │ ├── CMakeLists.txt │ ├── script/ │ │ ├── active_tasklet_profile.sh │ │ ├── build.sh │ │ ├── example.sh │ │ ├── function_profile.sh │ │ ├── instruction_mix_profile.sh │ │ ├── mram_access_pattern_profile.sh │ │ ├── timeline_profile.sh │ │ └── tlb_behavior_profile.sh │ └── src/ │ ├── CMakeLists.txt │ ├── abi/ │ │ └── instruction/ │ │ ├── op_code.h │ │ └── suffix.h │ ├── basic/ │ │ ├── instruction_parser.cc │ │ ├── instruction_parser.h │ │ ├── interval.cc │ │ ├── interval.h │ │ ├── reg_file_parser.cc │ │ ├── reg_file_parser.h │ │ ├── stats_parser.cc │ │ └── stats_parser.h │ ├── converter/ │ │ ├── op_code_converter.cc │ │ ├── op_code_converter.h │ │ ├── suffix_converter.cc │ │ └── suffix_converter.h │ ├── instruction_mix/ │ │ ├── instruction_mix_profiler.cc │ │ └── instruction_mix_profiler.h │ ├── main.cc │ ├── main.h │ └── util/ │ ├── argument_parser.cc │ ├── argument_parser.h │ └── config_loader.h └── upmem_reg_model/ ├── data/ │ ├── input.xlsx │ └── output.xlsx ├── script/ │ └── format.sh └── src/ ├── benchmark/ │ ├── _base_benchmark.py │ ├── bs.py │ ├── gemv.py │ ├── hst_l.py │ ├── hst_s.py │ ├── mlp.py │ ├── red.py │ ├── scan_rss.py │ ├── scan_ssa.py │ ├── sel.py │ ├── trns.py │ ├── ts.py │ ├── uni.py │ └── va.py ├── io_/ │ ├── excel_reader.py │ └── excel_writer.py ├── main.py └── regression/ ├── datum.py └── model.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.S *.bin bin/ build/ cmake-build-debug/ validation_log/ __pycache__/ .idea/ .vscode/ # Prerequisites *.d # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app ================================================ FILE: LICENSE ================================================ Copyright (c) 2024, VIA Research Group at KAIST Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # 📖 Introduction **Welcome to the uPIMulator Framework Documentation!** This documentation serves as your comprehensive guide to the uPIMulator framework, catering to both novice and experienced researchers. Here, you'll find the resources necessary to leverage uPIMulator effectively for your research projects. We provide in-depth coverage of uPIMulator's features, from foundational concepts to advanced functionalities. Explore this documentation to unlock the full potential of uPIMulator and elevate your research endeavors. # 🤙 Contact Information ## 📍 Address [KAIST](https://www.kaist.ac.kr/en/), School of Electrical Engineering [Vertically Integrated Architecture Research Group](https://sites.google.com/view/kaist-via/home) Office: N1 818 @ [KAIST](https://www.kaist.ac.kr/en/) ## 📧 Email - Bongjoon Hyun: [bongjoon.hyun@gmail.com](mailto:bongjoon.hyun@gmail.com) - Taehun Kim: [taehun.kim@kaist.ac.kr](mailto:taehun.kim@kaist.ac.kr) - Dongjae Lee: [dongjae.lee@kaist.ac.kr](mailto:dongjae.lee@kaist.ac.kr) - Minsoo Rhu: [minsoo.rhu@gmail.com](mailto:minsoo.rhu@gmail.com) Please feel free to reach out to us if you have any questions or require further assistance. # 🧑‍💻 Released Versions > **uPIMulator: A Flexible and Scalable Simulation Framework for General-Purpose Processing-In-Memory (PIM) Architectures** uPIMulator is a cycle-level performance simulator tailored for general-purpose Processing-In-Memory (PIM) systems adhering to the UPMEM Instruction Set Architecture (ISA). This tool provides a detailed simulation environment, empowering computer architecture researchers and PIM program developers to investigate and harness the capabilities of PIM technology. For comprehensive insights into uPIMulator and its applications, refer to our HPCA-2024 publication: "[Pathfinding Future PIM Architectures by Demystifying a Commercial PIM Technology](https://www.computer.org/csdl/proceedings-article/hpca/2024/931300a263/1VOAAZSdy0w)", HPCA, 2024 The currently available versions are: 1. Python & C++ version 2. Go version 3. Go & virtual machine version All source code and version history can be accessed in our GitHub repository. ## The Python & C++ Version This is our initial implementation of uPIMulator, used in our HPCA-2024 publication. You'll find it in the `python_cpp` directory. Refer to the included [README](./python_cpp/README.md) for usage instructions. ## The Go Version Our second implementation, optimized for speed and memory efficiency. Located in the `golang` directory, it offers an 8.5x speed increase and 7.5x memory reduction due to multi-threading. We generally recommend this version for most use cases. See the [README](./golang/README.md) for details. ## The Go & Virtual Machine Version This latest version extends the Go version with virtual machine capabilities, eliminating the need for manual data preparation code in many scenarios. It's particularly suitable for complex or dynamic benchmarks where manual data preparation is challenging, though it may not offer the fastest simulation speed. Refer to the [README](./golang_vm/README.md) for further guidance. # 🔍 Summary of Correlation Ratio (R²) and Mean Absolute Error (MAE) ## Single DPU ## Multiple DPUs - Each data point represents a single kernel from the PrIM benchmark suite. - Summary of Correlation Ratio (R²) and Mean Absolute Error (MAE) for single- and multi-DPU simulations: | Scenario | Total Data Points | Correlation (R²) | MAE | |---|---|---|---| | Single DPU (no inter-DPU communication) | 710 | 98.4% | 12.0% | | Multi-DPU (with inter-DPU communication) | 387 | 83.6% | 26.9% | - These validation results were obtained using the Python & C++ version of uPIMulator. # List of Supported Instructions - uPIMulator currently supports 599 out of the 970 instructions defined in the [UPMEM-PIM ISA](https://sdk.upmem.com/2023.2.0/201_IS.html#instruction-set-architecture). Due to limitations in the publicly available ISA documentation, support for the remaining 371 instructions is pending. However, the currently supported instructions have been sufficient to enable functionally correct simulations of the [PrIM benchmark suite](https://github.com/CMU-SAFARI/prim-benchmarks), producing results consistent with those obtained on real UPMEM-PIM hardware. - For a detailed list of the currently supported instructions, please refer to [this Google spreadsheet](https://docs.google.com/spreadsheets/d/1xq8t6aRvafmTlGmy4Am8i3QmoOzli1heNxLmCEIlCv4/edit?usp=sharing). # 🪨 Materials - Bongjoon Hyun, Taehun Kim, Dongjae Lee, and Minsoo Rhu, "[Pathfinding Future PIM Architectures by Demystifying a Commercial PIM Technology](https://www.computer.org/csdl/proceedings-article/hpca/2024/931300a263/1VOAAZSdy0w)", *The 30th IEEE International Symposium on High-Performance Computer Architecture ([HPCA-30](https://hpca-conf.org/2024/))*, Edinburgh, Scotland, Mar. 2024 - ${\textsf{\color{red}Best Paper Award}}$ - Acceptance rate: 18% (75 among 410) - [Slide](https://drive.google.com/file/d/1TRgFu6YdBu2gtdtDKIuJI85u8Be8w60M/view?usp=sharing) - [Presentation](https://youtu.be/e-RXYl568fw?si=LbTYbM7p7qod-L8w) # 🎁 Contributions We welcome and encourage contributions to uPIMulator! If you are interested in contributing or have questions, please feel free to open an issue or submit a pull request. ## List of Maintainers - Bongjoon Hyun (bongjoon.hyun@gmail.com) - Taehun Kim (taehun.kim@kaist.ac.kr) - Dongjae Lee (dongjae.lee@kaist.ac.kr) - Minsoo Rhu (minsoo.rhu@gmail.com) ## List of Contributors # 🙏 Acknowledgement We would like to thank the developers of the [PrIM benchmark suite](https://github.com/CMU-SAFARI/prim-benchmarks), which was instrumental in developing this project. This research is funded by the generous support from the following organizations: - Institute of Information & Communications Technology Planning & Evaluation (IITP) grant funded by the Korea government(MSIT) (No. 2022-0-01037, Development of High Performance Processing-in-Memory Technology based on DRAM) and the Korea government(MSIT) (No.RS-2024-00438851, (SW Starlab) High-performance Privacy-preserving Machine Learning System and System Software) - National Research Foundation of Korea (NRF) grant funded by the Korea government (MSIT) (NRF-2021R1A2C2091753) - Samsung Electronics We appreciate their commitment to advancing research in this field. ## 📔 Citation Bongjoon Hyun, Taehun Kim, Dongjae Lee, and Minsoo Rhu, "[Pathfinding Future PIM Architectures by Demystifying a Commercial PIM Technology](https://www.computer.org/csdl/proceedings-article/hpca/2024/931300a263/1VOAAZSdy0w)", IEEE International Symposium on High-Performance Computer Architecture (HPCA), March 2024. ================================================ FILE: golang/README.md ================================================ # ⚙️ Usage ## Currently Supported Mode uPIMulator operates in an execution-driven simulation mode, enabling cycle-level performance analysis of PIM-based applications. ## Workflow The typical usage workflow comprises two primary stages: 1. **Binary Generation:** Compile, assemble, and link your application code to generate the required binary files for simulation. 2. **Cycle-Level Simulation:** Utilize the generated binary files as input to the cycle-level simulator to obtain detailed performance metrics and insights. We are actively working on expanding uPIMulator's capabilities and may introduce additional usage modes in future releases. ## Installation & Build ### Prerequisites - **Go Compiler and SDK:** uPIMulator requires Go 1.21.5 or later. You can download and install Go from the [official website](https://go.dev/doc/install). - **Docker:** Please ensure that Docker is installed on your system. - **Docker Group Membership:** Your Ubuntu user account needs to be a member of the `docker` group. - **Tested Environment:** uPIMulator has been thoroughly tested on Ubuntu 18.04 with an Intel CPU. While we strive for compatibility across different environments, optimal performance and functionality are guaranteed within the tested setup. ### Installation Steps 1. **Install and Build** Navigate to the `uPIMulator` directory and execute the build script: ```bash cd /path/to/uPIMulator/golang/uPIMulator/script python build.py ``` ## Binary Files Generation & Cycle-Level Simulation We will use the VA (vector addition) benchmark as an example to demonstrate the binary file generation and simulation process. Please note that the initial simulation might take approximately 30 minutes. ### Execution To initiate a simulation, provide the following: - **Benchmark name:** Specify the desired benchmark (e.g., 'VA'). - **Number of tasklets:** Define the number of tasklets to be utilized. - **Output directory path:** Indicate the absolute path to the directory where you want to store binary files, log files, and other simulation artifacts. You can further customize the simulation by utilizing command-line options to adjust various parameters. ### Simulation Output Detailed simulation results will be written to the standard output (`stdout`). > **Important Notes:** > - **Create Output Directory:** Prior to running the simulation, create an empty directory at the specified `bin_dirpath`. > **Absolute Paths:** Always provide absolute paths for both `root_dirpath` (the repository's root directory) and `bin_dirpath`. ### Example Command ```bash cd /path/to/uPIMulator/golang/uPIMulator rm -rf bin mkdir bin ./build/uPIMulator --root_dirpath /path/to/uPIMulator/golang/uPIMulator --bin_dirpath /path/to/uPIMulator/golang/uPIMulator/bin --benchmark VA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets 16 --data_prep_params 1024 ``` # 📄 Reproducing Figures from the Paper To replicate the figures presented in our paper, please adhere to the instructions provided below. We offer replication manuals for Figures 5, 6, 7, 9 and 10 for brevity. ## Configuration of PrIM Benchmarks - **Single DPU Focus:** For Figures 5, 6, 7, and 9 the parameters `num_channels`, `num_ranks_per_channel`, and `num_dpus_per_rank` must always be set to `1`, as these experiments specifically characterize the behavior of a single DPU. - **Data Preparation Parameter:** When generating the binary files for the PrIM benchmarks, please configure the `data_prep_param` parameter according to the following table: | Benchmark | `data_prep_param` (Figures 5, 6) | `data_prep_param` (Figure 10) | |---|---|---| | BS | 32768 | 131072 | | GEMV | 2048 | 4096 | | HST-L | 131072 | 524288 | | HST-S | 131072 | 524288 | | MLP | 256 | 1024 | | RED | 524288 | 2097152| | SCAN-RSS | 262144 | 1048576| | SCAN-SSA | 262144 | 1048576| | SEL | 524288 | 2097152| | TRNS | 1024 | 128 | | TS | 2048 | 65536 | | UNI | 524288 | 2097152| | VA | 524288 | 2097152| ### Example Command ```bash ./uPIMulator --root_dirpath /path/to/uPIMulator/ --bin_dirpath /path/to/uPIMulator/bin --benchmark VA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets 16 --data_prep_params 524288 ``` Please ensure you adhere to these configurations to accurately replicate the figures presented in the paper. ## Figure 5: PrIM Compute and Memory Utilization This figure illustrates the compute utilization (represented by red points) and memory read bandwidth utilization (represented by blue points) of the PrIM benchmarks when executed with varying numbers of threads (tasklets): 1, 4, and 16. ### Metrics Calculation - **Compute Utilization (IPC):** `num_instructions` / `logic_cycle` - **Memory Read Bandwidth Utilization (GB/s):** Refer to the provided Excel sheet for the calculation: [link](../assets/figure5_mem_util_calculator.xlsx) > **Note:** The values for `num_instructions` and `logic_cycle` required in these calculations can be obtained from the simulation results generated by uPIMulator. ## Figure 6: DPU Runtime Breakdown This figure presents a breakdown of DPU runtime, categorizing cycles into: - **Active Cycles (Black):** Represent cycles when the DPU is actively executing instructions. - **Idle Cycles (Red, Yellow, Blue):** Represent cycles when the DPU is stalled due to various reasons. ### Calculation of Cycle Ratios To generate the breakdown depicted in the figure, you can utilize the following formulas: - **Issuable Ratio:** `breakdown_run` / `logic_cycle` - **Idle (Memory) Ratio:** `breakdown_dma` / `logic_cycle` - **Idle (Revolver) Ratio:** `breakdown_etc` / `logic_cycle` - **Idle (RF) Ratio:** `backpressure` / `logic_cycle` > **Note:** The values for the variables used in these formulas (`breakdown_run`, `logic_cycle`, etc.) are available in the simulation results produced by uPIMulator. ## Figure 7: Issuable Tasklets This figure visualizes the number of tasklets (threads) that are ready for execution (issuable) by the DPU scheduler at each cycle. ### Replication To reproduce this figure, utilize the provided [Excel sheet](../assets/figure7_active_tasklet_breakdown.xlsx). The spreadsheet includes instructions on how to populate it with the relevant simulation output data, and it will automatically generate the corresponding figure. > **Important Configuration Note**: Please ensure that the number of threads is configured to **16 tasklets** when running the simulations for this figure. > You can achieve this by using the following command-line argument: `--num_tasklets 16`. ## Figure 9: Instruction Mix (Single DPU) Figure 9 provides a breakdown of the instruction mix observed during single-DPU execution. To generate this figure, follow the steps outlined below using the `upmem_profiler` tool and the accompanying Excel sheet. ### Procedure 1. **Build the Profiler** ```bash cd /path/to/uPIMulator/tools/upmem_profiler/script bash build.sh ``` 2. **Extract Instructions** Run the simulation with the `--verbose 1` flag to capture detailed instruction traces. ```bash cd /path/to/uPIMulator/golang/uPIMulator/ ./build/uPIMulator --root_dirpath /path/to/uPIMulator/golang/uPIMulator --bin_dirpath /path/to/uPIMulator/golang/uPIMulator/bin --benchmark VA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets 16 --data_prep_params 1024 --verbose 1 > trace.txt ``` 3. **Run the Profiler** Process the generated trace file using the `upmem_profiler` in `instruction_mix` mode. ```bash cd /path/to/uPIMulator/tools/upmem_profiler/ ./build/src/upmem_profiler --logpath /path/to/uPIMulator/golang/uPIMulator/trace.txt --mode instruction_mix ``` 4. **Generate the Figure** Utilize the profiler's output to populate the provided [Excel sheet](../assets/figure9_instruction_mix.xlsx), which will automatically generate the instruction mix figure. > **Important Configuration Note:** Similar to Figure 7, the instruction mix analysis in Figure 9 is based on simulations with **16 tasklets**. > Ensure that you maintain this configuration (`--num_tasklets 16`) for accurate replication. ## Figure 10: Multi-DPU Latency Breakdown and Speedup Figure 10 presents the latency breakdown and speedup achieved in multi-DPU scenarios. ### Configuring the Number of DPUs You can adjust the number of DPUs by modifying the following parameters in `uPIMulator`: - `num_channels` - `num_ranks_per_channel` - `num_dpus_per_rank` ### Generating the Latency Breakdown To obtain the latency breakdown data for plotting, utilize the `upmem_reg_model` tool located in the `tools/upmem_reg_model/` directory. This tool implements a communication model between the host and DPUs based on linear regression. ### Procedure 1. **Prepare Input Excel:** - We provide a sample input Excel file as a template. - Append a new row to this file, specifying the benchmark name, number of DPUs, and the `data_prep_param` used in your simulation. - Fill in the relevant time values (in milliseconds) obtained from your simulation results, such as kernel execution time. You can convert cycle counts to time in milliseconds by dividing the cycle count by the corresponding clock frequency (in MHz) and then multiplying by 1000. 2. **Run the Regression Model:** ```bash cd /path/to/uPIMulator/tools/upmem_reg_model/src python main.py --input_excel_filepath /path/to/your/input_excel_file --output_excel_filepath /path/to/your/output_excel_file ``` 3. **Access the Output:** - The linear regression results will be available in the specified output Excel file. - Use this data to create the latency breakdown plots as shown in Figure 10. Please ensure that you follow these steps carefully to accurately reproduce the multi-DPU latency breakdown and speedup analysis presented in the paper. # 🌋 Adding Custom Benchmarks uPIMulator empowers you to go beyond the provided PrIM benchmark suite by incorporating your own custom benchmarks. This is particularly beneficial if you have access to UPMEM-PIM hardware and want to evaluate your code's performance in a simulated environment. ## Requirements To successfully integrate a new benchmark, ensure it adheres to the following: 1. **UPMEM-C Language:** The benchmark must be implemented in UPMEM-C, a C-like language tailored for UPMEM-PIM programming. Consult the [UPMEM SDK documentation](https://sdk.upmem.com/2021.4.0/) for detailed programming guidelines. 2. **File Structure and Naming:** - Maintain the same file hierarchy as the PrIM benchmarks, including a `dpu` subdirectory. - Include a `CMakeLists.txt` file within your benchmark's directory hierarchy, mirroring the structure used in the PrIM examples. This is essential as uPIMulator's interpreter and linker automatically detect and compile benchmarks using these `CMakeLists.txt` files. ## Data Preparation Since UPMEM PIM-enabled memory directly utilizes physical addresses and uPIMulator currently doesn't support concurrent execution of host and PIM-enabled memory, exercise caution when feeding input/output data. You'll need to provide Go source code to handle data preparation for your benchmark. This script should reside in the `uPIMulator/src/assembler` directory and be recognized by `uPIMulator/src/assembler/assembler.go`. > **Key Considerations for Data Preparation Scripts** > - Data transferred from the host to DPUs using `dpu_push_xfer` must be organized within the `input_dpu_mram_heap_pointer_name` variable in your data preparation script. > - Similarly, data transferred from DPUs to the host using `dpu_push_xfer` should be placed within the `output_dpu_mram_heap_pointer_name` variable. ## Reference Examples We have included data preparation scripts for the 13 supported PrIM benchmarks. These serve as excellent references for structuring your custom data preparation scripts. By following these guidelines, you can seamlessly integrate your benchmarks into uPIMulator for comprehensive performance evaluation and analysis. If you have any questions or encounter any difficulties during the integration process, don't hesitate to reach out to us for support. ================================================ FILE: golang/uPIMulator/benchmark/BS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/BS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 NR_DPUS ?= 1 PROBLEM_SIZE ?= 2 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) COMMON_INCLUDES := support HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DPROBLEM_SIZE=${PROBLEM_SIZE} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -i 262144 ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/cpu/Makefile ================================================ all: gcc bs_omp.c -o bs_omp -fopenmp run: ./bs_omp 262144 16777216 ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/cpu/README ================================================ Binary Search (BS) Compilation instructions: make Execution instructions ./bs_omp 2048576 16777216 ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/cpu/bs_omp.c ================================================ #include #include #include #include #include #include #include #include #include #include "timer.h" #define DTYPE uint64_t /* * @brief creates a "test file" by filling a bufferwith values */ void create_test_file(DTYPE * input, uint64_t nr_elements, DTYPE * querys, uint64_t n_querys) { uint64_t max = UINT64_MAX; uint64_t min = 0; srand(time(NULL)); input[0] = 1; for (uint64_t i = 1; i < nr_elements; i++) { input[i] = input[i - 1] + (rand() % 10) + 1; } for(uint64_t i = 0; i < n_querys; i++) { querys[i] = input[rand() % (nr_elements - 2)]; } } /** * @brief compute output in the host */ uint64_t binarySearch(DTYPE * input, uint64_t input_size, DTYPE* querys, unsigned n_querys) { uint64_t found = -1; uint64_t q, r, l, m; #pragma omp parallel for private(q,r,l,m) for(q = 0; q < n_querys; q++) { l = 0; r = input_size; while (l <= r) { m = l + (r - l) / 2; // Check if x is present at mid if (input[m] == querys[q]) { found += m; break; } // If x greater, ignore left half if (input[m] < querys[q]) l = m + 1; // If x is smaller, ignore right half else r = m - 1; } } return found; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { Timer timer; uint64_t input_size = atol(argv[1]); uint64_t n_querys = atol(argv[2]); printf("Vector size: %lu, num searches: %lu\n", input_size, n_querys); DTYPE * input = malloc((input_size) * sizeof(DTYPE)); DTYPE * querys = malloc((n_querys) * sizeof(DTYPE)); DTYPE result_host = -1; // Create an input file with arbitrary data. create_test_file(input, input_size, querys, n_querys); start(&timer, 0, 0); result_host = binarySearch(input, input_size - 1, querys, n_querys); stop(&timer, 0); int status = (result_host); if (status) { printf("[OK] Execution time: "); print(&timer, 0, 1); printf("ms.\n"); } else { printf("[ERROR]\n"); } free(input); return status ? 0 : 1; } ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/cpu/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/Makefile ================================================ all: nvcc -arch=sm_30 -m64 -Xcompiler -fPIC -shared -o cu_binary_search.so binary_search.cu -std=c++11 ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/README ================================================ Binary Search (BS) Compilation instructions: make Execution instructions python3 run.py ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/binary_search.cu ================================================ #include #include #include "binary_search.h" #include #include #define BLOCKDIM 512 #define SEARCH_CHUNK 16 #define BLOCK_CHUNK (BLOCKDIM*SEARCH_CHUNK) __global__ void search_kernel(const long int *arr, const long int len, const long int *querys, const long int num_querys, long int *res, bool *flag) { int search; if(*flag == false) { int tid = threadIdx.x; __shared__ int s_arr[BLOCK_CHUNK]; /* Since each value is being copied to shared memory, the rest of the following uncommented code is unncessary, since a direct comparison can be done at the time of copy below. */ // for(int i = 0; i < BLOCKDIM; ++i) { // int shared_loc = i*SEARCH_CHUNK + tid; // int global_loc = shared_loc + BLOCK_CHUNK * blockIdx.x; // if(arr[global_loc] == search) { // *flag = true; // *res = global_loc; // } // __syncthreads(); // } /* Copy chunk of array that this entire block of threads will read from the slower global memory to the faster shared memory. */ for(long int i = 0; i < SEARCH_CHUNK; ++i) { int shared_loc = tid*SEARCH_CHUNK + i; int global_loc = shared_loc + BLOCK_CHUNK * blockIdx.x; /* Make sure to stay within the bounds of the global array, else assign a dummy value. */ if(global_loc < len) { s_arr[shared_loc] = arr[global_loc]; } else { s_arr[shared_loc] = INT_MAX; } } __syncthreads(); for(long int i = 0; i < num_querys; i++) { search = querys[i]; /* For each runtime, set the initial search range. */ int L = 0; int R = SEARCH_CHUNK - 1; int m = (L + R) / 2; /* Pointer to the part of the shared array for this runtime. */ int *s_ptr = &s_arr[tid*SEARCH_CHUNK]; /* Each runtime will search a chunk of the block array. Many blocks will not find a solution so the search must be allowed to fail on a per block basis. The loop will break (fail) when L >= R. */ while(L <= R && *flag == false) { if(s_ptr[m] < search) { L = m + 1; } else if(s_ptr[m] > search) { R = m - 1; } else { *flag = true; *res = m += tid*SEARCH_CHUNK + BLOCK_CHUNK * blockIdx.x; } m = (L + R) / 2; } } } } int binary_search(const long int *arr, const long int len, const long int *querys, const long int num_querys) { long int *d_arr, *d_querys, *d_res; bool *d_flag; size_t arr_size = len * sizeof(long int); size_t querys_size = num_querys * sizeof(long int); size_t res_size = sizeof(long int); size_t flag_size = sizeof(bool); cudaMalloc(&d_arr, arr_size); cudaMalloc(&d_querys, querys_size); cudaMalloc(&d_res, res_size); cudaMalloc(&d_flag, flag_size); cudaMemcpy(d_arr, arr, arr_size, cudaMemcpyHostToDevice); cudaMemcpy(d_querys, querys, querys_size, cudaMemcpyHostToDevice); cudaMemset(d_flag, 0, flag_size); /* Set res value to -1, so that if the function returns -1, that indicates an algorithm failure. */ cudaMemset(d_res, -0x1, res_size); int blockSize = BLOCKDIM; int gridSize = (len-1)/BLOCK_CHUNK + 1; auto start = std::chrono::high_resolution_clock::now(); search_kernel<<>>(d_arr, len, d_querys, num_querys ,d_res, d_flag); cudaDeviceSynchronize(); auto end = std::chrono::high_resolution_clock::now(); std::cout << "Kernel Time: " << std::chrono::duration_cast(end-start).count() << " ms" << std::endl; long int res; cudaMemcpy(&res, d_res, res_size, cudaMemcpyDeviceToHost); return res; } ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/binary_search.h ================================================ #ifndef BINARY_SEARCH_H #define BINARY_SEARCH_H #ifdef _WIN32 #include #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT #endif extern "C" { int DLL_EXPORT binary_search(const long int *arr, const long int len, const long int *querys, const long int num_querys); } #endif /* BINARY_SEARCH_H */ ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/cpu_lib.py ================================================ # -*- coding: utf-8 -*- def binary_search(arr, search): L = 0 R = len(arr) while L <= R: if L > R: return -1 # Error code 1 m = (L + R) / 2 if arr[m] < search: L = m + 1 elif arr[m] > search: R = m - 1 else: return m return -2 # Error code 2 ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/cu_lib_import.py ================================================ # -*- coding: utf-8 -*- __all__ = [ "binary_search", ] import os.path as path import platform from ctypes import * from numpy.ctypeslib import load_library, ndpointer ## Load the DLL if platform.system() == "Linux": cuda_lib = load_library("cu_binary_search.so", path.dirname(path.realpath(__file__))) elif platform.system() == "Windows": cuda_lib = load_library("cu_binary_search.dll", path.dirname(path.realpath(__file__))) ## Define argtypes for all functions to import argtype_defs = { "binary_search": [ndpointer("i8"), c_int, ndpointer("i8"), c_int], } ## Import functions from DLL for func, argtypes in argtype_defs.items(): locals().update({func: cuda_lib[func]}) locals()[func].argtypes = argtypes ================================================ FILE: golang/uPIMulator/benchmark/BS/baselines/gpu/run.py ================================================ # -*- coding: utf-8 -*- import time import numpy as np # Local Imports from cu_lib_import import binary_search as gpu_search # Set an array label to create arr_len = 2048576 num_querys = 16777216 # Dummy array created arr = np.arange(0, arr_len, 1).astype("i8") # Random search querys created querys = np.random.randint(1, arr_len, num_querys) # GPU search function call t0 = time.time() res_gpu = gpu_search(arr, len(arr), querys, len(querys)) print("Total GPU Time: %i ms" % ((time.time() - t0) * 1e003)) ================================================ FILE: golang/uPIMulator/benchmark/BS/dpu/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/BS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS}") file(GLOB_RECURSE SRCS *.c) add_executable(BS_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/BS/dpu/task.c ================================================ /* * Binary Search with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Search DTYPE __attribute__ ((noinline)) search(DTYPE *bufferA, DTYPE searching_for) { DTYPE found = -2; if(bufferA[0] <= searching_for) { found = -1; for (uint32_t i = 0; i < BLOCK_SIZE / sizeof(DTYPE); i++){ if(bufferA[i] == searching_for) { found = i; break; } } } return found; } BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int(*kernels[nr_kernels])(void) = {main_kernel1}; int main(void){ // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if(tasklet_id == 0){ mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); DTYPE searching_for, found; uint64_t input_size = DPU_INPUT_ARGUMENTS.input_size; // Address of the current processing block in MRAM uint32_t start_mram_block_addr_A = (uint32_t) DPU_MRAM_HEAP_POINTER; uint32_t start_mram_block_addr_aux = start_mram_block_addr_A; uint32_t end_mram_block_addr_A = start_mram_block_addr_A + sizeof(DTYPE) * input_size; uint32_t current_mram_block_addr_query = end_mram_block_addr_A + tasklet_id * (DPU_INPUT_ARGUMENTS.slice_per_dpu / NR_TASKLETS) * sizeof(DTYPE); // Initialize a local cache to store the MRAM block DTYPE *cache_A = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_aux_A = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_aux_B = (DTYPE *) mem_alloc(BLOCK_SIZE); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; // TODO(bongjoon.hyun@gmail.com): original PrIM benchmark uses uint64_t for targets' type for(uint32_t targets = 0; targets < (DPU_INPUT_ARGUMENTS.slice_per_dpu / NR_TASKLETS); targets++) { found = -1; mram_read((__mram_ptr void const *) current_mram_block_addr_query, &searching_for, 8); current_mram_block_addr_query += 8; bool end = false; // Initialize input vector boundaries start_mram_block_addr_A = (uint32_t) DPU_MRAM_HEAP_POINTER; start_mram_block_addr_aux = start_mram_block_addr_A; end_mram_block_addr_A = start_mram_block_addr_A + sizeof(DTYPE) * input_size; uint32_t current_mram_block_addr_A = start_mram_block_addr_A; // Bring first and last values to WRAM mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_aux_A, BLOCK_SIZE); mram_read((__mram_ptr void const *) (end_mram_block_addr_A - BLOCK_SIZE * sizeof(DTYPE)), cache_aux_B, BLOCK_SIZE); current_mram_block_addr_A = (start_mram_block_addr_A + end_mram_block_addr_A) / 2; while(!end) { // Load cache with current MRAM block mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_A, BLOCK_SIZE); // Search inside block found = search(cache_A, searching_for); // If found > -1, we found the searching_for query if(found > -1) { result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); break; } // If found == -2, we need to discard right part of the input vector if(found == -2) { end_mram_block_addr_A = current_mram_block_addr_A; current_mram_block_addr_A = (current_mram_block_addr_A + start_mram_block_addr_A) / 2; } // If found == -1, we need to discard left part of the input vector else if (found == -1) { start_mram_block_addr_A = current_mram_block_addr_A; current_mram_block_addr_A = (current_mram_block_addr_A + end_mram_block_addr_A) / 2; } // Start boundary check if(current_mram_block_addr_A < (start_mram_block_addr_aux + BLOCK_SIZE)) { end = true; mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_A, BLOCK_SIZE); found = search(cache_A, searching_for); if(found > -1) { end = true; result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); } } // End boundary check if(current_mram_block_addr_A > (end_mram_block_addr_A - BLOCK_SIZE)) { end = true; mram_read((__mram_ptr void const *) end_mram_block_addr_A - BLOCK_SIZE, cache_A, BLOCK_SIZE); found = search(cache_A, searching_for); if(found > -1) { result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); } } } } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/BS/host/app.c ================================================ /** * app.c * BS Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include #if ENERGY #include #endif #include "params.h" #include "timer.h" // Define the DPU Binary path as DPU_BINARY here #define DPU_BINARY "./bin/bs_dpu" // Create input arrays void create_test_file(DTYPE * input, DTYPE * querys, uint64_t nr_elements, uint64_t nr_querys) { input[0] = 1; for (uint64_t i = 1; i < nr_elements; i++) { input[i] = input[i - 1] + 1; } for (uint64_t i = 0; i < nr_querys; i++) { querys[i] = i; } } // Compute output in the host int64_t binarySearch(DTYPE * input, DTYPE * querys, DTYPE input_size, uint64_t num_querys) { uint64_t result = -1; DTYPE r; for(uint64_t q = 0; q < num_querys; q++) { DTYPE l = 0; r = input_size; while (l <= r) { DTYPE m = l + (r - l) / 2; // Check if x is present at mid if (input[m] == querys[q]) result = m; // If x greater, ignore left half if (input[m] < querys[q]) l = m + 1; // If x is smaller, ignore right half else r = m - 1; } } return result; } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; uint64_t input_size = INPUT_SIZE; uint64_t num_querys = p.num_querys; DTYPE result_host = -1; DTYPE result_dpu = -1; // Create the timer Timer timer; // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Query number adjustement for proper partitioning if(num_querys % (nr_of_dpus * NR_TASKLETS)) num_querys = num_querys + (nr_of_dpus * NR_TASKLETS - num_querys % (nr_of_dpus * NR_TASKLETS)); assert(num_querys % (nr_of_dpus * NR_TASKLETS) == 0 && "Input dimension"); // Allocate input and querys vectors DTYPE * input = malloc((input_size) * sizeof(DTYPE)); DTYPE * querys = malloc((num_querys) * sizeof(DTYPE)); // Create an input file with arbitrary data create_test_file(input, querys, input_size, num_querys); // Compute host solution start(&timer, 0, 0); result_host = binarySearch(input, querys, input_size - 1, num_querys); stop(&timer, 0); // Create kernel arguments uint64_t slice_per_dpu = num_querys / nr_of_dpus; dpu_arguments_t input_arguments = {input_size, slice_per_dpu, 0}; for (unsigned int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Perform input transfers uint64_t i = 0; if (rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, input)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size * sizeof(DTYPE), DPU_XFER_DEFAULT)); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, querys + slice_per_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size * sizeof(DTYPE), slice_per_dpu * sizeof(DTYPE), DPU_XFER_DEFAULT)); if (rep >= p.n_warmup) stop(&timer, 1); // Run kernel on DPUs if (rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if (rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } // Print logs if required #if PRINT unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH(dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } #endif // Retrieve results if (rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); dpu_results_t* results_retrieve[nr_of_dpus]; i = 0; DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { for(unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if(results_retrieve[i][each_tasklet].found > result_dpu) { result_dpu = results_retrieve[i][each_tasklet].found; } } free(results_retrieve[i]); } if(rep >= p.n_warmup) stop(&timer, 3); } // Print timing results printf("CPU Version Time (ms): "); print(&timer, 0, p.n_reps); printf("CPU-DPU Time (ms): "); print(&timer, 1, p.n_reps); printf("DPU Kernel Time (ms): "); print(&timer, 2, p.n_reps); printf("DPU-CPU Time (ms): "); print(&timer, 3, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy * num_iterations); #endif int status = (result_dpu == result_host); if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] results are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] results differ!\n"); } free(input); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : 1; } ================================================ FILE: golang/uPIMulator/benchmark/BS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ #ifdef TL #define TASKLETS_INITIALIZER TASKLETS(TL, main, 2048, 2) #define NB_OF_TASKLETS_PER_DPU TL #else #define TASKLETS_INITIALIZER TASKLETS(16, main, 2048, 2) #define NB_OF_TASKLETS_PER_DPU 16 #endif // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #endif // Data type #define DTYPE int64_t // Vector size #define INPUT_SIZE 2048576 typedef struct { uint64_t input_size; uint64_t slice_per_dpu; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; // Structures used by both the host and the dpu to communicate information typedef struct { DTYPE found; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang/uPIMulator/benchmark/BS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { long num_querys; unsigned n_warmup; unsigned n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i problem size (default=2 queries)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.num_querys = PROBLEM_SIZE; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "h:i:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.num_querys = atol(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/BS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) project(benchmark) add_subdirectory(BS) add_subdirectory(GEMV) add_subdirectory(HST-L) add_subdirectory(HST-S) add_subdirectory(MLP) add_subdirectory(RED) add_subdirectory(SCAN-RSS) add_subdirectory(SCAN-SSA) add_subdirectory(SEL) add_subdirectory(TRNS) add_subdirectory(TS) add_subdirectory(UNI) add_subdirectory(VA) ================================================ FILE: golang/uPIMulator/benchmark/GEMV/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/GEMV/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -m 1024 -n 1024 ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_10_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_11_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_12_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_13_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_14_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_15_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_16 ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_16_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_17_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_18_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_19_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_1_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_20_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_21_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_22_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_23_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_24_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_2_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_3_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_4_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_5_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_6_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_7_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_8_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/_NR_TASKLETS_9_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/cpu/Makefile ================================================ all: gcc -o gemv -fopenmp gemv_openmp.c clean: rm gemv ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/cpu/README ================================================ Matrix-Vector Multiplication (GEMV) Compilation instructions: make Execution instructions ./gemv ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/cpu/gemv_openmp.c ================================================ #include #include #include "../../support/timer.h" #include "gemv_utils.h" int main(int argc, char *argv[]) { const size_t rows = 20480; const size_t cols = 8192; double **A, *b, *x; b = (double*) malloc(sizeof(double)*rows); x = (double*) malloc(sizeof(double)*cols); allocate_dense(rows, cols, &A); make_hilbert_mat(rows,cols, &A); #pragma omp parallel { #pragma omp for for (size_t i = 0; i < cols; i++) { x[i] = (double) i+1 ; } #pragma omp for for (size_t i = 0; i < rows; i++) { b[i] = (double) 0.0; } } Timer timer; start(&timer, 0, 0); gemv(A, x, rows, cols, &b); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); #if 0 print_vec(x, rows); print_mat(A, rows, cols); print_vec(b, rows); #endif printf("sum(x) = %f, sum(Ax) = %f\n", sum_vec(x,cols), sum_vec(b,rows)); return 0; } void gemv(double** A, double* x, size_t rows, size_t cols, double** b) { #pragma omp parallel for for (size_t i = 0; i < rows; i ++ ) for (size_t j = 0; j < cols; j ++ ) { (*b)[i] = (*b)[i] + A[i][j]*x[j]; } } void make_hilbert_mat(size_t rows, size_t cols, double*** A) { #pragma omp parallel for for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < cols; j++) { (*A)[i][j] = 1.0/( (double) i + (double) j + 1.0); } } } double sum_vec(double* vec, size_t rows) { double sum = 0.0; #pragma omp parallel for reduction(+:sum) for (int i = 0; i < rows; i++) sum = sum + vec[i]; return sum; } ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/cpu/gemv_utils.h ================================================ void allocate_dense(size_t rows,size_t cols, double*** dense) { *dense = malloc(sizeof(double)*rows); **dense = malloc(sizeof(double)*rows*cols); for (size_t i=0; i < rows; i++ ) { (*dense)[i] = (*dense)[0] + i*cols; } } void print_mat(double** A, size_t rows, size_t cols) { for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < cols; j++) { printf("%f ", A[i][j]); } printf("\n"); } } void print_vec(double* b, size_t rows) { for (size_t i = 0; i < rows; i++) { printf("%f\n", b[i]); } } void gemv(double** A, double* x, size_t rows, size_t cols, double** b); void make_hilbert_mat(size_t rows, size_t cols, double*** A); double sum_vec(double* vec, size_t rows); ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc gemv.cu -I/usr/local/cuda/include -lm -o gemv clean: rm gemv ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/gpu/README ================================================ Matrix-Vector Multiplication (GEMV) Compilation instructions: make Execution instructions ./gemv ================================================ FILE: golang/uPIMulator/benchmark/GEMV/baselines/gpu/gemv.cu ================================================ #include #include #include #include #define THREAD 128 #define T int __global__ void gemv(int m, int n, T *adim, T *b, T *d_ans); void cgemv(int m, int n, T *adim, T *b, T *d_ans); double gettime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1.0e-6; } int main(int argc, char **argv) { /* for CPU */ int i, j; int *bdim, *c, *ans, *h_ans; //double start, stop; //double cpu_time, gpu_time; int n = 8192; int m = 20480; bdim = (T*)malloc(sizeof(T) *m*n); c = (T*)malloc(sizeof(T) *n); ans = (T*)malloc(sizeof(T) *m); h_ans = (T*)malloc(sizeof(T) *m); /* for GPU */ T *d_bdim, *d_c, *d_ans; cudaMalloc((void **)&d_bdim, sizeof(T)*m*n); cudaMalloc((void **)&d_c, sizeof(T)*n); cudaMalloc((void **)&d_ans, sizeof(T)*m); for(i = 0; i < n; i++) { c[i] = 1; for(j = 0; j < m; j++) bdim[i*m+j] = 1; } //start = gettime(); cgemv(m, n, bdim, c, ans); //stop = gettime(); //cpu_time=stop - start; // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; cudaMemcpy(d_bdim, bdim, sizeof(T)*m*n, cudaMemcpyHostToDevice); cudaMemcpy(d_c, c, sizeof(T)*n, cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); //start = gettime(); gemv<<>>(m, n, d_bdim, d_c, d_ans); //stop = gettime(); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); //gpu_time=stop - start; cudaMemcpy(h_ans, d_ans, sizeof(T)*m, cudaMemcpyDeviceToHost); //printf("cpu_time : %.6f[sec]\n",cpu_time); //printf("gpu_time : %.6f[sec]\n",gpu_time); //printf("%f x\n", cpu_time / gpu_time); for(i = 0; i < m; i++) printf("%d -- %d\n", ans[i], h_ans[i]); printf("Execution time = %f ms\n", time1); free(bdim); free(c); free(ans); free(h_ans); cudaFree(d_bdim); cudaFree(d_c); cudaFree(d_ans); return 0; } __global__ void gemv(int m, int n, T* adim, T* b, T* d_ans) { int i; int div = n/THREAD; __shared__ T tmp[THREAD]; tmp[threadIdx.x] = 0.0; for(i = 0; i < div; i++) { tmp[threadIdx.x] += adim[blockIdx.x*n+i*THREAD+threadIdx.x] * b[i * THREAD + threadIdx.x]; } if(threadIdx.x < m%THREAD) tmp[threadIdx.x] += adim[blockIdx.x*n+THREAD*div+threadIdx.x] * b[THREAD * div + threadIdx.x]; __syncthreads(); for(i = THREAD / 2; i > 31; i = i / 2) { if(threadIdx.x < i) tmp[threadIdx.x] += tmp[threadIdx.x + i]; __syncthreads(); } if(threadIdx.x < 16) { tmp[threadIdx.x] += tmp[threadIdx.x + 16]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 8]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 4]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 2]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 1]; __syncthreads(); } if(threadIdx.x == 0) d_ans[blockIdx.x] = tmp[0]; } void cgemv(int m, int n, T *adim, T *b, T *d_ans) { int i, j; for(i = 0; i < m; i++) for(j = 0; j < n; j++) d_ans[i] += adim[i*n+j] * b[j]; } ================================================ FILE: golang/uPIMulator/benchmark/GEMV/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/GEMV/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(GEMV_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/GEMV/dpu/task.c ================================================ /* * Matrix vector multiplication with multiple tasklet * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // GEMV void __attribute__ ((noinline)) gemv(T *bufferC, T *bufferA, T *bufferB, int pos) { for (unsigned int i = 0; i < BLOCK_SIZE / sizeof(T); i++) { bufferC[pos] += bufferA[i] * bufferB[i]; } return; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // main int main() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); int32_t n_size = DPU_INPUT_ARGUMENTS.n_size; int32_t n_size_pad = DPU_INPUT_ARGUMENTS.n_size_pad; uint32_t nr_rows = DPU_INPUT_ARGUMENTS.nr_rows; uint32_t max_rows = DPU_INPUT_ARGUMENTS.max_rows; unsigned int nrows = nr_rows; unsigned int rows_per_tasklet; unsigned int start_row; unsigned int chunks = nrows / (NR_TASKLETS + NR_TASKLETS); unsigned int dbl_chunks = chunks + chunks; rows_per_tasklet = dbl_chunks; unsigned int rest_rows = nrows % (NR_TASKLETS + NR_TASKLETS); if ((tasklet_id + tasklet_id) < rest_rows) rows_per_tasklet += 2; if (rest_rows > 0) { if ((tasklet_id + tasklet_id) >= rest_rows) { unsigned int hlf_rest_rows = rest_rows >> 1; if ((rest_rows & 1) == 1) start_row = (hlf_rest_rows + 1) * (dbl_chunks + 2) + (tasklet_id - 1 - hlf_rest_rows) * dbl_chunks; else start_row = (hlf_rest_rows) * (dbl_chunks + 2) + (tasklet_id - hlf_rest_rows) * dbl_chunks; } else start_row = tasklet_id * (dbl_chunks + 2); } else { start_row = tasklet_id * (dbl_chunks); } // Address of the current row in MRAM uint32_t mram_base_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + start_row * n_size * sizeof(T)); uint32_t mram_base_addr_B = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T)); uint32_t mram_base_addr_C = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T) + n_size_pad * sizeof(T) + start_row * sizeof(T)); uint32_t mram_temp_addr_A = mram_base_addr_A; uint32_t mram_temp_addr_B = mram_base_addr_B; // Inititalize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE + 8); T *cache_A_aux = (T *) mem_alloc(8); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); T *cache_C = (T *) mem_alloc(8); int offset = 0; // Iterate over nr_rows for (unsigned int i = start_row; i < start_row + rows_per_tasklet; i += 2) { mram_temp_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + i * n_size * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; cache_C[0] = 0; cache_C[1] = 0; for(unsigned int pos = 0; pos < 2 && i + pos < nr_rows; pos++){ int n = 0, j; for (n = 0; n < (int32_t) (n_size - (BLOCK_SIZE/sizeof(T))); n += (BLOCK_SIZE / sizeof(T))) { mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) - 1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } // Compute GEMV gemv(cache_C, cache_A, cache_B, pos); // Update memory addresses mram_temp_addr_A += BLOCK_SIZE; mram_temp_addr_B += BLOCK_SIZE; } mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) -1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE ), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); for (j = 0; j < (int) (n_size - n); j++) { // Compute GEMV if(j >= (int)(BLOCK_SIZE / sizeof(T))){ printf("error\n"); break; } cache_C[pos] += cache_A[j] * cache_B[j]; } mram_temp_addr_A += (BLOCK_SIZE - ((BLOCK_SIZE / sizeof(T)) - (n_size - n)) * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; if(mram_temp_addr_A % 8 != 0) { offset = 1; } else { offset = 0; } } // Write cache to current MRAM block mram_write(cache_C, (__mram_ptr void *) (mram_base_addr_C), 8); // Update memory address mram_base_addr_C += 2 * sizeof(T); } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/GEMV/host/app.c ================================================ /** * app.c * GEMV Host Application Source File * */ #include #include #include #include #include #include #include #include #include #if ENERGY #include #endif #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/gemv_dpu" #endif static T* A; static T* B; static T* C; static T* C_dpu; // Create input arrays static void init_data(T* A, T* B, unsigned int m_size, unsigned int n_size) { srand(0); for (unsigned int i = 0; i < m_size * n_size; i++) { A[i] = (unsigned int) (rand()%50); } for (unsigned int i = 0; i < n_size; i++) { B[i] = (unsigned int) (rand()%50); } } // Compute output in the host static void gemv_host(T* C, T* A, T* B, unsigned int m_size, unsigned int n_size) { for (unsigned int i = 0; i < m_size; i++) { C[i] = 0; } for (unsigned int m = 0; m < m_size; m++) { for (unsigned int n = 0; n < n_size; n++) { C[m] += A[m * n_size + n] * B[n]; } } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif unsigned int i; unsigned int m_size = p.m_size; unsigned int n_size = p.n_size; // Initialize help data dpu_info = (struct dpu_info_t *) malloc(nr_of_dpus * sizeof(struct dpu_info_t)); dpu_arguments_t *input_args = (dpu_arguments_t *) malloc(nr_of_dpus * sizeof(dpu_arguments_t)); uint32_t max_rows_per_dpu = 0; uint32_t n_size_pad = n_size; if(n_size % 2 == 1) { n_size_pad++; } i = 0; DPU_FOREACH(dpu_set, dpu, i) { uint32_t rows_per_dpu; uint32_t prev_rows_dpu = 0; uint32_t chunks = m_size / nr_of_dpus; rows_per_dpu = chunks; uint32_t rest_rows = m_size % nr_of_dpus; if (i < rest_rows) rows_per_dpu++; if (rest_rows > 0) { if (i >= rest_rows) prev_rows_dpu = rest_rows * (chunks + 1) + (i - rest_rows) * chunks; else prev_rows_dpu = i * (chunks + 1); } else { prev_rows_dpu = i * chunks; } // Keep max rows for parallel transfers uint32_t rows_per_dpu_pad = rows_per_dpu; if (rows_per_dpu_pad % 2 == 1) // 4-byte elements rows_per_dpu_pad++; if (rows_per_dpu_pad > max_rows_per_dpu) max_rows_per_dpu = rows_per_dpu_pad; dpu_info[i].rows_per_dpu = rows_per_dpu; dpu_info[i].rows_per_dpu_pad = rows_per_dpu_pad; dpu_info[i].prev_rows_dpu = prev_rows_dpu; // Copy input arguments to DPU input_args[i].n_size = n_size; input_args[i].n_size_pad = n_size_pad; input_args[i].nr_rows = rows_per_dpu; } A = malloc(max_rows_per_dpu * nr_of_dpus * n_size_pad * sizeof(T)); B = malloc(n_size_pad * sizeof(T)); C = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(T)); // Initialize data with arbitrary data init_data(A, B, m_size, n_size); // Timer Timer timer; // Compute output on CPU (performance comparison and verification purposes) start(&timer, 0, 0); gemv_host(C, A, B, m_size, n_size); stop(&timer, 0); for (unsigned int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { if (rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments i = 0; DPU_FOREACH(dpu_set, dpu, i) { // Copy input arguments to DPU input_args[i].max_rows = max_rows_per_dpu; DPU_ASSERT(dpu_prepare_xfer(dpu, input_args + i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(dpu_arguments_t), DPU_XFER_DEFAULT)); // Copy input array and vector i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, A + dpu_info[i].prev_rows_dpu * n_size)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, B)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) , n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); if (rep >= p.n_warmup) stop(&timer, 1); // Run kernel on DPUs if (rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if (rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT // Display DPU Logs DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); } #endif // Retrieve results C_dpu = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(T)); if (rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, C_dpu + i * max_rows_per_dpu)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) + n_size_pad * sizeof(T), max_rows_per_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 3); } #if ENERGY double acc_energy, avg_energy, acc_time, avg_time; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_ACCUMULATE, &acc_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &avg_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_ACCUMULATE, &acc_time)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_AVERAGE, &avg_time)); #endif // Print timing results printf("CPU Version Time (ms): "); print(&timer, 0, 1); printf("CPU-DPU Time (ms): "); print(&timer, 1, p.n_reps); printf("DPU Kernel Time (ms): "); print(&timer, 2, p.n_reps); printf("DPU-CPU Time (ms): "); print(&timer, 3, p.n_reps); #if ENERGY printf("Energy (J): %f J\t", avg_energy); #endif // Check output bool status = true; unsigned int n,j; i = 0; for (n = 0; n < nr_of_dpus; n++) { for (j = 0; j < dpu_info[n].rows_per_dpu; j++) { if(C[i] != C_dpu[n * max_rows_per_dpu + j]) { status = false; #if PRINT // printf("%d: %d -- %d\n", i, C[i], C_dpu[n * max_rows_per_dpu + j]); #endif } i++; } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(B); free(C); free(C_dpu); DPU_ASSERT(dpu_free(dpu_set)); #if ENERGY DPU_ASSERT(dpu_probe_deinit(&probe)); #endif return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/GEMV/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t n_size; uint32_t n_size_pad; uint32_t nr_rows; uint32_t max_rows; } dpu_arguments_t; // Specific information for each DPU struct dpu_info_t { uint32_t rows_per_dpu; uint32_t rows_per_dpu_pad; uint32_t prev_rows_dpu; }; struct dpu_info_t *dpu_info; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang/uPIMulator/benchmark/GEMV/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int m_size; unsigned int n_size; unsigned int n_warmup; unsigned int n_reps; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -m m_size (default=8192 elements)" "\n -n n_size (default=8192 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.m_size = 8192; p.n_size = 8192; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hm:n:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'm': p.m_size = atoi(optarg); break; case 'n': p.n_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/GEMV/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); //printf("Time (ms): %f\t",((timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + // (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec)) / 1000); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/HST-L/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/HST-L/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 8 NR_DPUS ?= 1 NR_HISTO ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_NR_DPUS_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${NR_DPUS}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -DNR_HISTO=${NR_HISTO} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/HST-L/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(NR_HISTO 1) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/HST-L/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -DNR_HISTO=${NR_HISTO}") file(GLOB_RECURSE SRCS *.c) add_executable(HST-L_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/HST-L/dpu/task.c ================================================ /* * Histogram (HST-L) with multiple tasklets * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // Array for communication between adjacent tasklets uint32_t* message[NR_TASKLETS]; // DPU histogram uint32_t* histo_dpu; // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); ATOMIC_BIT_INIT(barriers_mutexes)[NR_HISTO]; barrier_t barriers[NR_HISTO]; // Mutex mutex_id_t my_mutex[NR_HISTO]; // Histogram in each tasklet void __attribute__ ((noinline)) histogram(uint32_t* histo, uint32_t bins, T *input, uint32_t histo_id, unsigned int l_size){ for(unsigned int j = 0; j < l_size; j++) { T d = (input[j] * bins) >> DEPTH; mutex_lock(my_mutex[histo_id]); histo[d] += 1; mutex_unlock(my_mutex[histo_id]); } } extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif unsigned int l_tasklet_id = tasklet_id / NR_HISTO; unsigned int nr_l_tasklet = NR_TASKLETS / NR_HISTO; unsigned int my_histo_id = tasklet_id & (NR_HISTO - 1); if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap // Initialize barriers for (unsigned int each_barrier = 0; each_barrier < NR_HISTO; each_barrier++) { barriers[each_barrier].wait_queue = 0xff; barriers[each_barrier].count = nr_l_tasklet; barriers[each_barrier].initial_count = nr_l_tasklet; barriers[each_barrier].lock = (uint8_t) &ATOMIC_BIT_GET(barriers_mutexes)[each_barrier]; } } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes uint32_t bins = DPU_INPUT_ARGUMENTS.bins; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_histo = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local histogram if (tasklet_id < NR_HISTO){ // Allocate DPU histogram uint32_t *histo = (uint32_t *) mem_alloc(bins * sizeof(uint32_t)); message[tasklet_id] = histo; } // Barrier barrier_wait(&barriers[my_histo_id]); uint32_t *my_histo = message[my_histo_id]; // Initialize local histogram for(unsigned int i = l_tasklet_id; i < bins; i += nr_l_tasklet){ my_histo[i] = 0; } // Barrier barrier_wait(&barriers[my_histo_id]); // Compute histogram for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Histogram in each tasklet histogram(my_histo, bins, cache_A, my_histo_id, l_size_bytes >> DIV); } // Barrier barrier_wait(&my_barrier); uint32_t *histo_dpu = message[0]; for (unsigned int i = tasklet_id; i < bins; i += NR_TASKLETS){ uint32_t b = 0; for (unsigned int j = 0; j < NR_HISTO; j++){ b += *(message[j] + i); } histo_dpu[i] = b; } // Barrier barrier_wait(&my_barrier); // Write dpu histogram to current MRAM block if(tasklet_id == 0){ if(bins * sizeof(uint32_t) <= 2048) mram_write(histo_dpu, (__mram_ptr void*)(mram_base_addr_histo), bins * sizeof(uint32_t)); else for(unsigned int offset = 0; offset < ((bins * sizeof(uint32_t)) >> 11); offset++){ mram_write(histo_dpu + (offset << 9), (__mram_ptr void*)(mram_base_addr_histo + (offset << 11)), 2048); } } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/HST-L/host/app.c ================================================ /** * app.c * HST-L Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static unsigned int* histo_host; static unsigned int* histo; // Create input arrays static void read_input(T* A, const Params p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, p.file_name); if((File = fopen(dctFileName, "rb")) != NULL) { for(unsigned int y = 0; y < p.input_size; y++) { fread(&temp, sizeof(unsigned short), 1, File); A[y] = (unsigned int)ByteSwap16(temp); if(A[y] >= 4096) A[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } // Compute output in the host static void histogram_host(unsigned int* histo, T* A, unsigned int bins, unsigned int nr_elements, int exp, unsigned int nr_of_dpus) { if(!exp){ for (unsigned int i = 0; i < nr_of_dpus; i++) { for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[(d * bins) >> DEPTH] += 1; } } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; unsigned int input_size; // Size of input image unsigned int dpu_s = p.dpu_s; if(p.exp == 0) input_size = p.input_size * nr_of_dpus; // Size of input image else if(p.exp == 1) input_size = p.input_size; // Size of input image else input_size = p.input_size * dpu_s; // Size of input image const unsigned int input_size_8bytes = ((input_size * sizeof(T)) % 8) != 0 ? roundup(input_size, 8) : input_size; // Input size per DPU (max.), 8-byte aligned const unsigned int input_size_dpu = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_8bytes = ((input_size_dpu * sizeof(T)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); T *bufferA = A; histo_host = malloc(p.bins * sizeof(unsigned int)); histo = malloc(nr_of_dpus * p.bins * sizeof(unsigned int)); // Create an input file with arbitrary data read_input(A, p); if(p.exp == 0){ for(unsigned int j = 1; j < nr_of_dpus; j++){ memcpy(&A[j * input_size_dpu_8bytes], &A[0], input_size_dpu_8bytes * sizeof(T)); } } else if(p.exp == 2){ for(unsigned int j = 1; j < dpu_s; j++) memcpy(&A[j * p.input_size], &A[0], p.input_size * sizeof(T)); } // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\tinput_size\t%u\n", NR_TASKLETS, BL, input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { memset(histo_host, 0, p.bins * sizeof(unsigned int)); memset(histo, 0, nr_of_dpus * p.bins * sizeof(unsigned int)); // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); histogram_host(histo_host, A, p.bins, p.input_size, 1, nr_of_dpus); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments unsigned int kernel = 0; i = 0; dpu_arguments_t input_arguments[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); i = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, histo + p.bins * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu_8bytes * sizeof(T), p.bins * sizeof(unsigned int), DPU_XFER_DEFAULT)); // Final histogram merging for(i = 1; i < nr_of_dpus; i++){ for(unsigned int j = 0; j < p.bins; j++){ histo[j] += histo[j + i * p.bins]; } } if(rep >= p.n_warmup) stop(&timer, 3); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("DPU-CPU "); print(&timer, 3, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; if(p.exp == 1) for (unsigned int j = 0; j < p.bins; j++) { if(histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, histo_host[j], histo[j]); #endif } } else if(p.exp == 2) for (unsigned int j = 0; j < p.bins; j++) { if(dpu_s * histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, dpu_s * histo_host[j], histo[j]); #endif } } else for (unsigned int j = 0; j < p.bins; j++) { if(nr_of_dpus * histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, nr_of_dpus * histo_host[j], histo[j]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(histo_host); free(histo); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/HST-L/run.sh ================================================ #!/bin/bash for i in 1 do for b in 64 128 256 512 1024 2048 4096 do for k in 1 2 4 8 16 do NR_DPUS=$i NR_TASKLETS=$k BL=10 make all wait ./bin/host_code -w 2 -e 5 -b ${b} > profile/HSTL_${b}_tl${k}_dpu${i}.txt wait make clean wait done done done ================================================ FILE: golang/uPIMulator/benchmark/HST-L/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #define REGS (BLOCK_SIZE >> 2) // 32 bits // Pixel depth #define DEPTH 12 #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; uint32_t transfer_size; uint32_t bins; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-L/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int dpu_s; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1, 2) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.file_name = "./input/image_VanHateren.iml"; p.dpu_s = 64; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:z:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 'z': p.dpu_s = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-L/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/HST-S/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/cpu/Makefile ================================================ all: gcc -o hist -fopenmp app_baseline.c clean: rm hist ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/cpu/README ================================================ Histogram - input partition (HST) Compilation instructions: make Execution instructions ./hist -y 1006632960 -t 4 For more options: ./hsti -h ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/cpu/app_baseline.c ================================================ /* * JGL@SAFARI */ /** * @file app.c * @brief Template for a Host Application Source File. * * The macros DPU_BINARY and NR_TASKLETS are directly * used in the static functions, and are not passed as arguments of these functions. */ #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" // Pointer declaration static T* A; static unsigned int* histo_host; typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int n_threads; }Params; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, const Params p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, p.file_name); if((File = fopen(dctFileName, "rb")) != NULL) { for(unsigned int y = 0; y < p.input_size; y++) { fread(&temp, sizeof(unsigned short), 1, File); A[y] = (unsigned int)ByteSwap16(temp); if(A[y] >= 4096) A[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } /** * @brief compute output in the host */ static void histogram_host(unsigned int* histo, T* A, unsigned int bins, unsigned int nr_elements, int exp, unsigned int nr_of_dpus, int t) { omp_set_num_threads(t); if(!exp){ #pragma omp parallel for for (unsigned int i = 0; i < nr_of_dpus; i++) { for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ #pragma omp parallel for for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; #pragma omp atomic update histo[(d * bins) >> DEPTH] += 1; } } } // Params --------------------------------------------------------------------- void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -t # of threads (default=8)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 8; p.exp = 1; p.file_name = "../../input/image_VanHateren.iml"; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); uint32_t nr_of_dpus; const unsigned int input_size = p.input_size; // Size of input image if(!p.exp) assert(input_size % p.n_threads == 0 && "Input size!"); else assert(input_size % p.n_threads == 0 && "Input size!"); // Input/output allocation A = malloc(input_size * sizeof(T)); T *bufferA = A; if(!p.exp) histo_host = malloc(nr_of_dpus * p.bins * sizeof(unsigned int)); else histo_host = malloc(p.bins * sizeof(unsigned int)); // Create an input file with arbitrary data. read_input(A, p); Timer timer; start(&timer, 0, 0); if(!p.exp) memset(histo_host, 0, nr_of_dpus * p.bins * sizeof(unsigned int)); else memset(histo_host, 0, p.bins * sizeof(unsigned int)); histogram_host(histo_host, A, p.bins, input_size, p.exp, nr_of_dpus, p.n_threads); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=/usr/local/cuda/bin/nvcc CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -L/usr/local/cuda/lib64 -lm INC=-I/usr/local/cuda/include DEP=kernel.cpp kernel.h main.cpp kernel.cu support/common.h support/cuda-setup.h support/partitioner.h support/timer.h support/verify.h SRC=main.cpp kernel.cpp kernel.cu EXE=hsti all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) $(INC) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/README ================================================ Histogram - input partition (HST) Compilation instructions: make Execution instructions ./hsti -n 1006632960 -g 512 For more options: ./hsti -h Note: The input folder contains one image from Van Hateren's natural image database (http://www.kyb.tuebingen.mpg.de/?id=227). Image pixels are 12-bit depth. Thus, for calculation of the B-bin histogram of an image, the corresponding histogram bin is computed as ((pixel * B) >> 12). Monochrome images from other databases or synthetic images can also be used. The read input function (in main.cpp) might need to be changed accordingly. If image pixels are b-bit depth and the histogram contains B bins, the histogram bin will be computed as ((pixel * B) >> b). ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "kernel.h" #include "support/partitioner.h" #include #include #include #include // CPU threads-------------------------------------------------------------------------------------- void run_cpu_threads(std::atomic_uint *histo, unsigned int *data, int size, int bins, int n_threads, int chunk, int n_tasks, float alpha #ifdef CUDA_8_0 , std::atomic_int *worklist #endif ) { std::vector cpu_threads; for(int k = 0; k < n_threads; k++) { cpu_threads.push_back(std::thread([=]() { #ifdef CUDA_8_0 Partitioner p = partitioner_create(n_tasks, alpha, k, n_threads, worklist); #else Partitioner p = partitioner_create(n_tasks, alpha, k, n_threads); #endif unsigned int Hs[bins]; // Local histogram initialization for(int i = 0; i < bins; i++) { Hs[i] = 0; } for(int i = cpu_first(&p); cpu_more(&p); i = cpu_next(&p)) { for(int j = 0; j < chunk; j++) { // Read pixel unsigned int d = ((data[i * chunk + j] * bins) >> 12); // Vote in histogram Hs[d]++; } } // Merge to global histogram for(int i = 0; i < bins; i++) { (&histo[i])->fetch_add(Hs[i]); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.cu ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #define _CUDA_COMPILER_ #include "support/common.h" #include "support/partitioner.h" // CUDA kernel ------------------------------------------------------------------------------------------ __global__ void Histogram_kernel(int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo #ifdef CUDA_8_0 , int *worklist #endif ) { extern __shared__ unsigned int l_mem[]; unsigned int* l_histo = l_mem; #ifdef CUDA_8_0 int* l_tmp = (int*)&l_histo[bins]; #endif #ifdef CUDA_8_0 Partitioner p = partitioner_create(n_tasks, alpha, worklist, l_tmp); #else Partitioner p = partitioner_create(n_tasks, alpha); #endif // Block and runtime index const int bx = blockIdx.x; const int tx = threadIdx.x; const int bD = blockDim.x; const int gD = gridDim.x; // Sub-histograms initialization for(int pos = tx; pos < bins; pos += bD) { l_histo[pos] = 0; } __syncthreads(); // Intra-block synchronization // Main loop for(int i = gpu_first(&p); gpu_more(&p); i = gpu_next(&p)) { // Global memory read unsigned int d = data[i * bD + tx]; // Atomic vote in shared memory atomicAdd(&l_histo[((d * bins) >> 12)], 1); } __syncthreads(); // Intra-block synchronization // Merge per-block histograms and write to global memory for(int pos = tx; pos < bins; pos += bD) { // Atomic addition in global memory #ifdef CUDA_8_0 atomicAdd_system(histo + pos, l_histo[pos]); #else atomicAdd(histo + pos, l_histo[pos]); #endif } } cudaError_t call_Histogram_kernel(int blocks, int threads, int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo, int l_mem_size #ifdef CUDA_8_0 , int* worklist #endif ){ dim3 dimGrid(blocks); dim3 dimBlock(threads); Histogram_kernel<<>>(size, bins, n_tasks, alpha, data, histo #ifdef CUDA_8_0 , worklist #endif ); cudaError_t err = cudaGetLastError(); return err; } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include "support/common.h" void run_cpu_threads(std::atomic_uint *histo, unsigned int *data, int size, int bins, int num_threads, int chunk, int n_tasks, float alpha #ifdef CUDA_8_0 , std::atomic_int *wl #endif ); cudaError_t call_Histogram_kernel(int blocks, int threads, int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo, int l_mem_size #ifdef CUDA_8_0 , int* worklist #endif ); ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/cuda-setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include // Params --------------------------------------------------------------------- struct Params { int device; int n_gpu_threads; int n_gpu_blocks; int n_threads; int n_warmup; int n_reps; float alpha; int in_size; int n_bins; Params(int argc, char **argv) { device = 0; n_gpu_threads = 256; n_gpu_blocks = 16; n_threads = 4; n_warmup = 5; n_reps = 50; alpha = 0.2; in_size = 1536 * 1024 * 640; n_bins = 256; int opt; while((opt = getopt(argc, argv, "hd:i:g:t:w:r:a:n:b:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': device = atoi(optarg); break; case 'i': n_gpu_threads = atoi(optarg); break; case 'g': n_gpu_blocks = atoi(optarg); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'a': alpha = atof(optarg); break; case 'n': in_size = atoi(optarg); break; case 'b': n_bins = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } if(alpha == 0.0) { assert(n_gpu_threads > 0 && "Invalid # of device threads!"); assert(n_gpu_blocks > 0 && "Invalid # of device blocks!"); } else if(alpha == 1.0) { assert(n_threads > 0 && "Invalid # of host threads!"); } else if(alpha > 0.0 && alpha < 1.0) { assert(n_gpu_threads > 0 && "Invalid # of device threads!"); assert(n_gpu_blocks > 0 && "Invalid # of device blocks!"); assert(n_threads > 0 && "Invalid # of host threads!"); } else { #ifdef CUDA_8_0 assert((n_gpu_threads > 0 && n_gpu_blocks > 0 || n_threads > 0) && "Invalid # of host + device workers!"); #else assert(0 && "Illegal value for -a"); #endif } } void usage() { fprintf(stderr, "\nUsage: ./hsti [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d CUDA device ID (default=0)" "\n -i # of device threads per block (default=256)" "\n -g # of device blocks (default=16)" "\n -t # of host threads (default=4)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n -a fraction of input elements to process on host (default=0.2)" #ifdef CUDA_8_0 "\n NOTE: Dynamic partitioning used when is not between 0.0 and 1.0" #else "\n NOTE: must be between 0.0 and 1.0" #endif "\n" "\nBenchmark-specific options:" "\n -n input size (default=1572864, i.e., 1536x1024)" "\n -b # of bins in histogram (default=256)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(unsigned int *input, const Params &p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, "./input/image_VanHateren.iml"); if((File = fopen(dctFileName, "rb")) != NULL) { for(int y = 0; y < p.in_size; y++) { int fr = fread(&temp, sizeof(unsigned short), 1, File); input[y] = (unsigned int)ByteSwap16(temp); if(input[y] >= 4096) input[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { Params p(argc, argv); CUDASetup setcuda(p.device); Timer timer; cudaError_t cudaStatus; // Allocate buffers timer.start("Allocation"); int n_tasks = divceil(p.in_size, p.n_gpu_threads); #ifdef CUDA_8_0 unsigned int *h_in; cudaStatus = cudaMallocManaged(&h_in, p.in_size * sizeof(unsigned int)); std::atomic_uint *h_histo; cudaStatus = cudaMallocManaged(&h_histo, p.n_bins * sizeof(std::atomic_uint)); unsigned int * d_in = h_in; std::atomic_uint *d_histo = h_histo; std::atomic_int * worklist; cudaStatus = cudaMallocManaged(&worklist, sizeof(std::atomic_int)); #else unsigned int * h_in = (unsigned int *)malloc(p.in_size * sizeof(unsigned int)); std::atomic_uint *h_histo = (std::atomic_uint *)malloc(p.n_bins * sizeof(std::atomic_uint)); unsigned int * h_histo_merge = (unsigned int *)malloc(p.n_bins * sizeof(unsigned int)); unsigned int * d_in; cudaStatus = cudaMalloc((void**)&d_in, p.in_size * sizeof(unsigned int)); unsigned int * d_histo; cudaStatus = cudaMalloc((void**)&d_histo, p.n_bins * sizeof(unsigned int)); ALLOC_ERR(h_in, h_histo, h_histo_merge); #endif CUDA_ERR(); cudaDeviceSynchronize(); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); const int max_gpu_threads = setcuda.max_gpu_threads(); read_input(h_in, p); #ifdef CUDA_8_0 for(int i = 0; i < p.n_bins; i++) { h_histo[i].store(0); } #else memset(h_histo, 0, p.n_bins * sizeof(unsigned int)); #endif cudaDeviceSynchronize(); timer.stop("Initialization"); timer.print("Initialization", 1); #ifndef CUDA_8_0 // Copy to device timer.start("Copy To Device"); cudaStatus = cudaMemcpy(d_in, h_in, p.in_size * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_histo, h_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaDeviceSynchronize(); CUDA_ERR(); timer.stop("Copy To Device"); timer.print("Copy To Device", 1); #endif // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset #ifdef CUDA_8_0 if(p.alpha < 0.0 || p.alpha > 1.0) { // Dynamic partitioning worklist[0].store(0); } for(int i = 0; i < p.n_bins; i++) { h_histo[i].store(0); } #else memset(h_histo, 0, p.n_bins * sizeof(unsigned int)); cudaStatus = cudaMemcpy(d_histo, h_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaDeviceSynchronize(); CUDA_ERR(); #endif if(rep >= p.n_warmup) timer.start("Kernel"); p.n_gpu_blocks = p.in_size / p.n_gpu_threads; // Launch GPU threads // Kernel launch if(p.n_gpu_blocks > 0) { assert(p.n_gpu_threads <= max_gpu_threads && "The runtime block size is greater than the maximum runtime block size that can be used on this device"); cudaStatus = call_Histogram_kernel(p.n_gpu_blocks, p.n_gpu_threads, p.in_size, p.n_bins, n_tasks, p.alpha, d_in, (unsigned int*)d_histo, p.n_bins * sizeof(unsigned int) #ifdef CUDA_8_0 + sizeof(int), (int*)worklist #endif ); CUDA_ERR(); } // Launch CPU threads std::thread main_thread(run_cpu_threads, h_histo, h_in, p.in_size, p.n_bins, p.n_threads, p.n_gpu_threads, n_tasks, p.alpha #ifdef CUDA_8_0 , worklist #endif ); cudaDeviceSynchronize(); main_thread.join(); if(rep >= p.n_warmup) timer.stop("Kernel"); } timer.print("Kernel", p.n_reps); #ifndef CUDA_8_0 // Copy back timer.start("Copy Back and Merge"); cudaStatus = cudaMemcpy(h_histo_merge, d_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyDeviceToHost); CUDA_ERR(); cudaDeviceSynchronize(); for(unsigned int i = 0; i < p.n_bins; ++i) { h_histo_merge[i] += (unsigned int)h_histo[i]; } timer.stop("Copy Back and Merge"); timer.print("Copy Back and Merge", 1); #endif // Verify answer #ifdef CUDA_8_0 verify((unsigned int *)h_histo, h_in, p.in_size, p.n_bins); #else verify((unsigned int *)h_histo_merge, h_in, p.in_size, p.n_bins); #endif // Free memory timer.start("Deallocation"); #ifdef CUDA_8_0 cudaStatus = cudaFree(h_in); cudaStatus = cudaFree(h_histo); cudaStatus = cudaFree(worklist); #else free(h_in); free(h_histo); free(h_histo_merge); cudaStatus = cudaFree(d_in); cudaStatus = cudaFree(d_histo); #endif CUDA_ERR(); cudaDeviceSynchronize(); timer.stop("Deallocation"); timer.print("Deallocation", 1); // Release timers timer.release("Allocation"); timer.release("Initialization"); timer.release("Copy To Device"); timer.release("Kernel"); timer.release("Copy Back and Merge"); timer.release("Deallocation"); printf("Test Passed\n"); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/support/cuda-setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) #define CUDA_ERR() \ if(cudaStatus != cudaSuccess) { \ fprintf(stderr, "CUDA error: %s\n at %s, %d\n", cudaGetErrorString(cudaStatus), __FILE__, __LINE__); \ exit(-1); \ } struct CUDASetup { cudaDeviceProp device_prop; CUDASetup(int device) { cudaError_t cudaStatus; cudaStatus = cudaSetDevice(device); CUDA_ERR(); cudaStatus = cudaGetDeviceProperties(&device_prop, device); CUDA_ERR(); fprintf(stderr, "%s\t", device_prop.name); } int max_gpu_threads() { return device_prop.maxThreadsPerBlock; } }; ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/support/partitioner.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _PARTITIONER_H_ #define _PARTITIONER_H_ #ifndef _CUDA_COMPILER_ #include #endif #if !defined(_CUDA_COMPILER_) && defined(CUDA_8_0) #include #endif // Partitioner definition ----------------------------------------------------- typedef struct Partitioner { int n_tasks; int cut; int current; #ifndef _CUDA_COMPILER_ int thread_id; int n_threads; #endif #ifdef CUDA_8_0 // CUDA 8.0 support for dynamic partitioning int strategy; #ifdef _CUDA_COMPILER_ int *worklist; int *tmp; #else std::atomic_int *worklist; #endif #endif } Partitioner; // Partitioning strategies #define STATIC_PARTITIONING 0 #define DYNAMIC_PARTITIONING 1 // Create a partitioner ------------------------------------------------------- #ifdef _CUDA_COMPILER_ __device__ #endif inline Partitioner partitioner_create(int n_tasks, float alpha #ifndef _CUDA_COMPILER_ , int thread_id, int n_threads #endif #ifdef CUDA_8_0 #ifdef _CUDA_COMPILER_ , int *worklist , int *tmp #else , std::atomic_int *worklist #endif #endif ) { Partitioner p; p.n_tasks = n_tasks; #ifndef _CUDA_COMPILER_ p.thread_id = thread_id; p.n_threads = n_threads; #endif if(alpha >= 0.0 && alpha <= 1.0) { p.cut = p.n_tasks * alpha; #ifdef CUDA_8_0 p.strategy = STATIC_PARTITIONING; #endif } else { #ifdef CUDA_8_0 p.strategy = DYNAMIC_PARTITIONING; p.worklist = worklist; #ifdef _CUDA_COMPILER_ p.tmp = tmp; #endif #endif } return p; } // Partitioner iterators: first() --------------------------------------------- #ifndef _CUDA_COMPILER_ inline int cpu_first(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { p->current = p->worklist->fetch_add(1); } else #endif { p->current = p->thread_id; } return p->current; } #else __device__ inline int gpu_first(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { if(threadIdx.y == 0 && threadIdx.x == 0) { p->tmp[0] = atomicAdd_system(p->worklist, 1); } __syncthreads(); p->current = p->tmp[0]; } else #endif { p->current = p->cut + blockIdx.x; } return p->current; } #endif // Partitioner iterators: more() ---------------------------------------------- #ifndef _CUDA_COMPILER_ inline bool cpu_more(const Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { return (p->current < p->n_tasks); } else #endif { return (p->current < p->cut); } } #else __device__ inline bool gpu_more(const Partitioner *p) { return (p->current < p->n_tasks); } #endif // Partitioner iterators: next() ---------------------------------------------- #ifndef _CUDA_COMPILER_ inline int cpu_next(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { p->current = p->worklist->fetch_add(1); } else #endif { p->current = p->current + p->n_threads; } return p->current; } #else __device__ inline int gpu_next(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { if(threadIdx.y == 0 && threadIdx.x == 0) { p->tmp[0] = atomicAdd_system(p->worklist, 1); } __syncthreads(); p->current = p->tmp[0]; } else #endif { p->current = p->current + gridDim.x; } return p->current; } #endif #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { cudaEventCreate(&startTime[name]); cudaEventCreate(&stopTime[name]); time[name] = 0.0; } cudaEventRecord(startTime[name], 0); } void stop(string name) { cudaEventRecord(stopTime[name],0); cudaEventSynchronize(stopTime[name]); float part_time = 0.0; cudaEventElapsedTime(&part_time, startTime[name], stopTime[name]); time[name] += part_time; } void print(string name, unsigned int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / REP); } void release(string name){ cudaEventDestroy(startTime[name]); cudaEventDestroy(stopTime[name]); } }; ================================================ FILE: golang/uPIMulator/benchmark/HST-S/baselines/gpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include #include inline int compare_output(unsigned int *outp, unsigned int *outpCPU, int bins) { for(int i = 0; i < bins; i++) { if(outp[i] != outpCPU[i]) { printf("Test failed\n"); exit(EXIT_FAILURE); } } return 0; } // Sequential implementation for comparison purposes inline void HistogramCPU(unsigned int *histo, unsigned int *data, int size, int bins) { for(int i = 0; i < size; i++) { // Read pixel unsigned int d = ((data[i] * bins) >> 12); // Vote in histogram histo[d]++; } } inline void verify(unsigned int *histo, unsigned int *input, int size, int bins) { unsigned int *gold = (unsigned int *)malloc(bins * sizeof(unsigned int)); memset(gold, 0, bins * sizeof(unsigned int)); HistogramCPU(gold, input, size, bins); compare_output(histo, gold, bins); free(gold); } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/HST-S/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(HST-S_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/HST-S/dpu/task.c ================================================ /* * Histogram (HST-S) with multiple tasklets * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // Array for communication between adjacent tasklets uint32_t* message[NR_TASKLETS]; // DPU histogram uint32_t* histo_dpu; // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Histogram in each tasklet void __attribute__ ((noinline)) histogram(uint32_t* histo, uint32_t bins, T *input, unsigned int l_size){ for(unsigned int j = 0; j < l_size; j++) { T d = input[j]; histo[(d * bins) >> DEPTH] += 1; } } extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes uint32_t bins = DPU_INPUT_ARGUMENTS.bins; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_histo = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local histogram uint32_t *histo = (uint32_t *) mem_alloc(bins * sizeof(uint32_t)); // Initialize local histogram for(unsigned int i = 0; i < bins; i++){ histo[i] = 0; } // Compute histogram for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Histogram in each tasklet histogram(histo, bins, cache_A, l_size_bytes >> DIV); } message[tasklet_id] = histo; // Barrier barrier_wait(&my_barrier); uint32_t *histo_dpu = message[0]; for (unsigned int i = tasklet_id; i < bins; i += NR_TASKLETS){ uint32_t b = 0; for (unsigned int j = 0; j < NR_TASKLETS; j++){ b += *(message[j] + i); } histo_dpu[i] = b; } // Barrier barrier_wait(&my_barrier); // Write dpu histogram to current MRAM block if(tasklet_id == 0){ if(bins * sizeof(uint32_t) <= 2048) mram_write(histo_dpu, (__mram_ptr void*)(mram_base_addr_histo), bins * sizeof(uint32_t)); else for(unsigned int offset = 0; offset < ((bins * sizeof(uint32_t)) >> 11); offset++){ mram_write(histo_dpu + (offset << 9), (__mram_ptr void*)(mram_base_addr_histo + (offset << 11)), 2048); } } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/host/app.c ================================================ /** * app.c * HST-S Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static unsigned int* histo_host; static unsigned int* histo; // Create input arrays static void read_input(T* A, const Params p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, p.file_name); if((File = fopen(dctFileName, "rb")) != NULL) { for(unsigned int y = 0; y < p.input_size; y++) { fread(&temp, sizeof(unsigned short), 1, File); A[y] = (unsigned int)ByteSwap16(temp); if(A[y] >= 4096) A[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } // Compute output in the host static void histogram_host(unsigned int* histo, T* A, unsigned int bins, unsigned int nr_elements, int exp, unsigned int nr_of_dpus) { if(!exp){ for (unsigned int i = 0; i < nr_of_dpus; i++) { for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[(d * bins) >> DEPTH] += 1; } } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; unsigned int input_size; // Size of input image unsigned int dpu_s = p.dpu_s; if(p.exp == 0) input_size = p.input_size * nr_of_dpus; // Size of input image else if(p.exp == 1) input_size = p.input_size; // Size of input image else input_size = p.input_size * dpu_s; // Size of input image const unsigned int input_size_8bytes = ((input_size * sizeof(T)) % 8) != 0 ? roundup(input_size, 8) : input_size; // Input size per DPU (max.), 8-byte aligned const unsigned int input_size_dpu = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_8bytes = ((input_size_dpu * sizeof(T)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); T *bufferA = A; histo_host = malloc(p.bins * sizeof(unsigned int)); histo = malloc(nr_of_dpus * p.bins * sizeof(unsigned int)); // Create an input file with arbitrary data read_input(A, p); if(p.exp == 0){ for(unsigned int j = 1; j < nr_of_dpus; j++){ memcpy(&A[j * input_size_dpu_8bytes], &A[0], input_size_dpu_8bytes * sizeof(T)); } } else if(p.exp == 2){ for(unsigned int j = 1; j < dpu_s; j++) memcpy(&A[j * p.input_size], &A[0], p.input_size * sizeof(T)); } // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\tinput_size\t%u\n", NR_TASKLETS, BL, input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { memset(histo_host, 0, p.bins * sizeof(unsigned int)); memset(histo, 0, nr_of_dpus * p.bins * sizeof(unsigned int)); // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); histogram_host(histo_host, A, p.bins, p.input_size, 1, nr_of_dpus); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments unsigned int kernel = 0; i = 0; dpu_arguments_t input_arguments[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); i = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, histo + p.bins * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu_8bytes * sizeof(T), p.bins * sizeof(unsigned int), DPU_XFER_DEFAULT)); // Final histogram merging for(i = 1; i < nr_of_dpus; i++){ for(unsigned int j = 0; j < p.bins; j++){ histo[j] += histo[j + i * p.bins]; } } if(rep >= p.n_warmup) stop(&timer, 3); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("DPU-CPU "); print(&timer, 3, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; if(p.exp == 1) for (unsigned int j = 0; j < p.bins; j++) { if(histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, histo_host[j], histo[j]); #endif } } else if(p.exp == 2) for (unsigned int j = 0; j < p.bins; j++) { if(dpu_s * histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, dpu_s * histo_host[j], histo[j]); #endif } } else for (unsigned int j = 0; j < p.bins; j++) { if(nr_of_dpus * histo_host[j] != histo[j]){ status = false; #if PRINT printf("%u - %u: %u -- %u\n", j, j, nr_of_dpus * histo_host[j], histo[j]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(histo_host); free(histo); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/HST-S/run.sh ================================================ #!/bin/bash for i in 1 do for b in 64 128 256 512 1024 2048 4096 do for k in 1 2 4 8 16 do NR_DPUS=$i NR_TASKLETS=$k BL=10 make all wait ./bin/host_code -w 2 -e 5 -b ${b} -x 1 > profile/HSTS_${b}_tl${k}_dpu${i}.txt wait make clean wait done done done ================================================ FILE: golang/uPIMulator/benchmark/HST-S/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #define REGS (BLOCK_SIZE >> 2) // 32 bits // Pixel depth #define DEPTH 12 #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; uint32_t transfer_size; uint32_t bins; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-S/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int dpu_s; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1, 2) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.file_name = "./input/image_VanHateren.iml"; p.dpu_s = 64; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:z:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 'z': p.dpu_s = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/HST-S/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/MLP/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/MLP/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -m 1024 -n 1024 ================================================ FILE: golang/uPIMulator/benchmark/MLP/_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_10_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_11_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_12_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_13_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_14_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_15_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_16 ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_16_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_17_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_18_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_19_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_1_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_20_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_21_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_22_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_23_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_24_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_2_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_3_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_4_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_5_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_6_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_7_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_8_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/_NR_TASKLETS_9_BL_10.conf ================================================ ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/cpu/Makefile ================================================ all: gcc mlp_openmp.c -o mlp_openmp -fopenmp -std=c99 run: ./mlp_openmp ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/cpu/README ================================================ Multilayer Perceptron (MLP) Compilation instructions make Execution instructions ./mlp_openmp ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/cpu/mlp_openmp.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include "../../support/timer.h" #include "../../support/common.h" T** A; T* B; T* C; // Create input arrays static void init_data(T** A, T* B, unsigned int m_size, unsigned int n_size){ for (unsigned int l = 0; l < NUM_LAYERS; l++) for (unsigned int i = 0; i < m_size * n_size; i++){ if(i % 100 < 98){ A[l][i] = 0; }else{ A[l][i] = (l+i) % 2; } } for (unsigned int i = 0; i < n_size; i++){ if(i % 50 < 48){ B[i] = 0; } else{ B[i] = i % 2; } } } // Compute output in the host static void mlp_host(T* C, T** A, T* B, unsigned int m_size, unsigned int n_size) { for (unsigned int nl = 0; nl < NUM_LAYERS; nl++){ for (unsigned int m = 0; m < m_size; m++){ C[m] = 0; } #pragma omp parallel for for (unsigned int m = 0; m < m_size; m++){ for (unsigned int n = 0; n < n_size; n++){ C[m] += A[nl][m * n_size + n] * B[n]; } C[m] = max(0, C[m]); } for (unsigned int n = 0; n < n_size; n++){ B[n] = C[n]; } } } static uint64_t mlp_host_sum(uint64_t n_size, uint64_t m_size) { uint64_t sum = 0; for (uint64_t m = 0; m < n_size; m++){ sum += B[m]; } return sum; } // Params --------------------------------------------------------------------- typedef struct Params { char* dpu_type; int nr_of_ranks; int input_size_n; int input_size_m; int n_warmup; int n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d DPU type (default=fsim)" "\n -r # of ranks (default=2)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.dpu_type = "fsim"; p.nr_of_ranks = 1; p.input_size_n = 1 << 9; p.input_size_m = 1 << 9; p.n_warmup = 2; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hd:r:i:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': p.dpu_type = optarg; break; case 'r': p.nr_of_ranks = atoi(optarg); break; case 'n': p.input_size_n = atoi(optarg); break; case 'm': p.input_size_m = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.nr_of_ranks > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); uint64_t n_size = 8192; uint64_t m_size = 20480; Timer timer; A = malloc(NUM_LAYERS * sizeof(T*)); for(int l = 0; l < NUM_LAYERS; l++) A[l] = malloc(n_size*m_size*sizeof(unsigned int)); B = malloc(m_size*sizeof(unsigned int)); C = malloc(m_size*sizeof(unsigned int)); // Create an input file with arbitrary data. init_data(A, B, m_size, n_size); start(&timer, 0, 1); mlp_host(C, A, B, n_size, m_size); stop(&timer, 0); uint32_t sum = mlp_host_sum(n_size, m_size); printf("Kernel "); print(&timer, 0, 1); printf("\n"); printf("SUM = %d \n", sum); for(int l = 0; l < NUM_LAYERS; l++) free(A[l]); free(A); free(B); free(C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc mlp.cu -I/usr/local/cuda/include -lm -o mlp clean: rm mlp ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/gpu/README ================================================ Multilayer Perceptron (MLP) Compilation instructions make Execution instructions ./mlp ================================================ FILE: golang/uPIMulator/benchmark/MLP/baselines/gpu/mlp.cu ================================================ #include #include #include #include #include "../../support/common.h" #define THREAD 128 __global__ void gemv(int m, int n, T *adim, T *b, T *d_ans); void cgemv(int m, int n, T *adim, T *b, T *d_ans); double gettime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1.0e-6; } int main(int argc, char **argv) { /* for CPU */ int i, j; T **bdim; T *c, *ans, *h_ans, *h_c; int n = 8192; int m = 20480; bdim = (T**) malloc(NUM_LAYERS * sizeof(T*)); for(int l = 0; l < NUM_LAYERS; l++) bdim[l] = (T*)malloc(sizeof(T)*m*n); c = (T*)malloc(sizeof(T) *n); h_c = (T*)malloc(sizeof(T) *n); ans = (T*)malloc(sizeof(T) *m); h_ans = (T*)malloc(sizeof(T) *m); /* for GPU */ T *d_bdim; T *d_c, *d_ans; cudaMalloc((void **)&d_bdim, sizeof(T)*m*n); cudaMalloc((void **)&d_c, sizeof(T)*n); cudaMalloc((void **)&d_ans, sizeof(T)*m); for(i = 0; i < n; i++) { if(i % 50 < 48) { c[i] = 0; h_c[i] = 0; } else { c[i] = i % 2; h_c[i] = i % 2; } } for(int l = 0; l < NUM_LAYERS; l++) for(i = 0; i < n; i++) { for(j = 0; j < m; j++){ if(j % 100 < 98) { bdim[l][i*m+j] = 0; } else { bdim[l][i*m+j] = (l + i) % 2; } } } for(j = 0; j < m; j++){ ans[j] = 0; h_ans[j] = 0; } // Computation on the host for verification T* vector = c; T* output = ans; T* matrix; int mm = m; int nn = n; for(int l = 0; l < NUM_LAYERS; l++){ matrix = bdim[l]; cgemv(mm, nn, matrix, vector, output); vector = output; h_ans = output; mm = n; nn = m; } // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; cudaMemcpy(d_ans, h_ans, sizeof(T)*m, cudaMemcpyHostToDevice); cudaMemcpy(d_c, h_c, sizeof(T)*n, cudaMemcpyHostToDevice); vector = d_c; output = d_ans; mm = m; nn = n; for(int l = 0; l < NUM_LAYERS; l++){ cudaMemcpy(d_bdim, bdim[l], sizeof(T)*m*n, cudaMemcpyHostToDevice); matrix = d_bdim; // Start timer cudaEventRecord( start, 0 ); gemv<<>>(mm, nn, matrix, vector, output); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time2, start, stop ); time1 += time2; vector = output; d_ans = output; mm = n; nn = m; } cudaMemcpy(h_ans, d_ans, sizeof(T)*m, cudaMemcpyDeviceToHost); cudaMemcpy(h_c, d_c, sizeof(T)*n, cudaMemcpyDeviceToHost); for(i = 0; i < m; i++) { if(ans[i] != h_ans[i]) printf("ERROR in Ans %d -> %d -- %d\n", i, ans[i], h_ans[i]); } for(i = 0; i < n; i++) { if(c[i] != h_c[i]) printf("ERROR in C %d -> %d -- %d\n", i, c[i], h_c[i]); } printf("Execution time = %f ms\n", time1); for(int l = 0; l < NUM_LAYERS; l++) free(bdim[l]); free(bdim); free(c); free(ans); free(h_c); cudaFree(d_bdim); cudaFree(d_c); cudaFree(d_ans); cudaEventDestroy(start); cudaEventDestroy(stop); return 0; } __global__ void gemv(int m, int n, T* adim, T* b, T* d_ans) { int i; int div = n/THREAD; __shared__ T tmp[THREAD]; tmp[threadIdx.x] = 0.0; for(i = 0; i < div; i++){ tmp[threadIdx.x] += adim[blockIdx.x*n+i*THREAD+threadIdx.x] * b[i * THREAD + threadIdx.x]; } if(threadIdx.x < m%THREAD) tmp[threadIdx.x] += adim[blockIdx.x*n+THREAD*div+threadIdx.x] * b[THREAD * div + threadIdx.x]; __syncthreads(); for(i = THREAD / 2; i > 31; i = i / 2) { if(threadIdx.x < i) tmp[threadIdx.x] += tmp[threadIdx.x + i]; __syncthreads(); } if(threadIdx.x < 16) { tmp[threadIdx.x] += tmp[threadIdx.x + 16]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 8]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 4]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 2]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 1]; __syncthreads(); } if(threadIdx.x == 0) d_ans[blockIdx.x] = max(0, tmp[0]); } void cgemv(int m, int n, T *adim, T *b, T *d_ans) { int i, j; for(i = 0; i < m; i++){ for(j = 0; j < n; j++) d_ans[i] += adim[i*n+j] * b[j]; d_ans[i] = max(0, d_ans[i]); } } ================================================ FILE: golang/uPIMulator/benchmark/MLP/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/MLP/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(MLP_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/MLP/dpu/task.c ================================================ /* * Matrix vector multiplication with multiple tasklet * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // GEMV void __attribute__ ((noinline)) gemv(T *bufferC, T *bufferA, T *bufferB, int pos) { for (unsigned int i = 0; i < BLOCK_SIZE / sizeof(T); i++) { bufferC[pos] += bufferA[i] * bufferB[i]; } return; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // main int main() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); int32_t n_size = DPU_INPUT_ARGUMENTS.n_size; int32_t n_size_pad = DPU_INPUT_ARGUMENTS.n_size_pad; uint32_t nr_rows = DPU_INPUT_ARGUMENTS.nr_rows; uint32_t max_rows = DPU_INPUT_ARGUMENTS.max_rows; unsigned int nrows = nr_rows; unsigned int rows_per_tasklet; unsigned int start_row; unsigned int chunks = nrows / (NR_TASKLETS + NR_TASKLETS); unsigned int dbl_chunks = chunks + chunks; rows_per_tasklet = dbl_chunks; unsigned int rest_rows = nrows % (NR_TASKLETS + NR_TASKLETS); if ((tasklet_id + tasklet_id) < rest_rows) rows_per_tasklet += 2; if (rest_rows > 0) { if ((tasklet_id + tasklet_id) >= rest_rows) { unsigned int hlf_rest_rows = rest_rows >> 1; if ((rest_rows & 1) == 1) start_row = (hlf_rest_rows + 1) * (dbl_chunks + 2) + (tasklet_id - 1 - hlf_rest_rows) * dbl_chunks; else start_row = (hlf_rest_rows) * (dbl_chunks + 2) + (tasklet_id - hlf_rest_rows) * dbl_chunks; } else start_row = tasklet_id * (dbl_chunks + 2); } else { start_row = tasklet_id * (dbl_chunks); } // Address of the current row in MRAM uint32_t mram_base_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + start_row * n_size * sizeof(T)); uint32_t mram_base_addr_B = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T)); uint32_t mram_base_addr_C = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T) + n_size_pad * sizeof(T) + start_row * sizeof(T)); uint32_t mram_temp_addr_A = mram_base_addr_A; uint32_t mram_temp_addr_B = mram_base_addr_B; // Inititalize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE + 8); T *cache_A_aux = (T *) mem_alloc(8); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); T *cache_C = (T *) mem_alloc(8); int offset = 0; // Iterate over nr_rows for (unsigned int i = start_row; i < start_row + rows_per_tasklet; i += 2) { mram_temp_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + i * n_size * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; cache_C[0] = 0; cache_C[1] = 0; for(unsigned int pos = 0; pos < 2 && i + pos < nr_rows; pos++){ int n = 0, j; for (n = 0; n < (int32_t) (n_size - (BLOCK_SIZE/sizeof(T))); n += (BLOCK_SIZE / sizeof(T))) { mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) - 1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } // Compute GEMV gemv(cache_C, cache_A, cache_B, pos); // Update memory addresses mram_temp_addr_A += BLOCK_SIZE; mram_temp_addr_B += BLOCK_SIZE; } mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) -1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE ), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); for (j = 0; j < (int) (n_size - n); j++) { // Compute GEMV if(j >= (int)(BLOCK_SIZE / sizeof(T))){ printf("error\n"); break; } cache_C[pos] += cache_A[j] * cache_B[j]; } mram_temp_addr_A += (BLOCK_SIZE - ((BLOCK_SIZE / sizeof(T)) - (n_size - n)) * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; if(mram_temp_addr_A % 8 != 0) { offset = 1; } else { offset = 0; } } // Write cache to current MRAM block mram_write(cache_C, (__mram_ptr void *) (mram_base_addr_C), 8); // Update memory address mram_base_addr_C += 2 * sizeof(T); } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/MLP/host/app.c ================================================ /** * app.c * MLP Host Application Source File * */ #include #include #include #include #include #include #include #include #include #if ENERGY #include #endif #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/mlp_dpu" #endif static T** A; static T* B; static T* B_host; static T* B_tmp; static T* C; static T* C_dpu; // Create input arrays static void init_data(T** A, T* B, T* B_host, unsigned int m_size, unsigned int n_size) { for (unsigned int l = 0; l < NUM_LAYERS; l++) for (unsigned int i = 0; i < m_size * n_size; i++){ if(i % 100 < 98){ A[l][i] = 0; }else{ A[l][i] = (l+i) % 2; } } for (unsigned int i = 0; i < n_size; i++){ if(i % 50 < 48){ B[i] = 0; } else{ B[i] = i % 2; } B_host[i] = B[i]; } } // Compute output in the host static void mlp_host(T* C, T** A, T* B, unsigned int m_size, unsigned int n_size) { for (unsigned int nl = 0; nl < NUM_LAYERS; nl++){ for (unsigned int m = 0; m < m_size; m++){ C[m] = 0; } for (unsigned int m = 0; m < m_size; m++){ for (unsigned int n = 0; n < n_size; n++){ C[m] += A[nl][m * n_size + n] * B[n]; } C[m] = max(0, C[m]); } for (unsigned int n = 0; n < n_size; n++){ B[n] = C[n]; } } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif unsigned int i, l; unsigned int m_size = p.m_size; unsigned int n_size = p.n_size; // Initialize help data dpu_info = (struct dpu_info_t *) malloc(nr_of_dpus * sizeof(struct dpu_info_t)); dpu_arguments_t *input_args = (dpu_arguments_t *) malloc(nr_of_dpus * sizeof(dpu_arguments_t)); uint32_t max_rows_per_dpu = 0; uint32_t n_size_pad = n_size; if(n_size % 2 == 1){ n_size_pad++; } // Timer Timer timer; i = 0; DPU_FOREACH(dpu_set, dpu, i) { uint32_t rows_per_dpu; uint32_t prev_rows_dpu = 0; uint32_t chunks = m_size / nr_of_dpus; rows_per_dpu = chunks; uint32_t rest_rows = m_size % nr_of_dpus; if (i < rest_rows) rows_per_dpu++; if (rest_rows > 0) { if (i >= rest_rows) prev_rows_dpu = rest_rows * (chunks + 1) + (i - rest_rows) * chunks; else prev_rows_dpu = i * (chunks + 1); } else { prev_rows_dpu = i * chunks; } // Keep max rows for parallel transfers uint32_t rows_per_dpu_pad = rows_per_dpu; if (rows_per_dpu_pad % 2 == 1) // 4-byte elements rows_per_dpu_pad++; if (rows_per_dpu_pad > max_rows_per_dpu) max_rows_per_dpu = rows_per_dpu_pad; dpu_info[i].rows_per_dpu = rows_per_dpu; dpu_info[i].rows_per_dpu_pad = rows_per_dpu_pad; dpu_info[i].prev_rows_dpu = prev_rows_dpu; // Copy input arguments to DPU input_args[i].n_size = n_size; input_args[i].n_size_pad = n_size_pad; input_args[i].nr_rows = rows_per_dpu; } A = (T**)malloc(NUM_LAYERS * sizeof(T*)); for(l = 0; l < NUM_LAYERS; l++) A[l] = (T*)malloc( max_rows_per_dpu * nr_of_dpus * n_size_pad * sizeof(T)); B = (T*)malloc(n_size * sizeof(T)); B_host = (T*)malloc(n_size * sizeof(T)); C = (T*)malloc(m_size * sizeof(T)); C_dpu = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(T)); B_tmp = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(T)); init_data(A, B, B_host, m_size, n_size); // Compute output on CPU (performance comparison and verification purposes) start(&timer, 0, 0); mlp_host(C, A, B_host, m_size, n_size); stop(&timer, 0); for (unsigned int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { if (rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments i = 0; // Copy input arguments to DPU DPU_FOREACH(dpu_set, dpu, i) { input_args[i].max_rows = max_rows_per_dpu; DPU_ASSERT(dpu_prepare_xfer(dpu, input_args + i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(dpu_arguments_t), DPU_XFER_DEFAULT)); // Copy input array and vector i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, A[0] + dpu_info[i].prev_rows_dpu * n_size)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, B)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) , n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); if (rep >= p.n_warmup) stop(&timer, 1); // Run kernel on DPUs if (rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if (rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } for(int lay = 1; lay < NUM_LAYERS; lay++){ if (rep >= p.n_warmup) start(&timer, 4, rep - p.n_warmup); i = 0; // Copy C_dpu DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, C_dpu + i * max_rows_per_dpu)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) + n_size_pad * sizeof(T), max_rows_per_dpu * sizeof(T), DPU_XFER_DEFAULT)); // B = C unsigned int n, j; i = 0; for (n = 0; n < nr_of_dpus; n++) { for (j = 0; j < dpu_info[n].rows_per_dpu; j++) { B_tmp[i] = C_dpu[n * max_rows_per_dpu + j]; i++; } } i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, B_tmp)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) , n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); // Copy next matrix of weights i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, A[lay] + dpu_info[i].prev_rows_dpu * n_size)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 4); if (rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if (rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } } #if PRINT // Display DPU Logs DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); } #endif // Retrieve results if (rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, C_dpu + i * max_rows_per_dpu)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(T) + n_size_pad * sizeof(T), max_rows_per_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 3); } #if ENERGY double acc_energy, avg_energy, acc_time, avg_time; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_ACCUMULATE, &acc_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &avg_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_ACCUMULATE, &acc_time)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_AVERAGE, &avg_time)); #endif // Print timing results printf("CPU Version Time (ms): "); print(&timer, 0, 1); printf("CPU-DPU Time (ms): "); print(&timer, 1, p.n_reps); printf("DPU Kernel Time (ms): "); print(&timer, 2, p.n_reps); printf("Inter-DPU Time (ms): "); print(&timer, 4, p.n_reps); printf("DPU-CPU Time (ms): "); print(&timer, 3, p.n_reps); #if ENERGY printf("Energy (J): %f J\t", avg_energy); #endif printf("\n\n"); // Check output bool status = true; unsigned int n, j; i = 0; for (n = 0; n < nr_of_dpus; n++) { for (j = 0; j < dpu_info[n].rows_per_dpu; j++) { if(C[i] != C_dpu[n * max_rows_per_dpu + j]) { status = false; #if PRINT printf("%d: %d -- %d\n", i, C[i], C_dpu[n * max_rows_per_dpu + j]); #endif } i++; } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation for(i = 0; i < NUM_LAYERS; i++) free(A[i]); free(A); free(B); free(C); free(C_dpu); DPU_ASSERT(dpu_free(dpu_set)); #if ENERGY DPU_ASSERT(dpu_probe_deinit(&probe)); #endif return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/MLP/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t n_size; uint32_t n_size_pad; uint32_t nr_rows; uint32_t max_rows; } dpu_arguments_t; // Specific information for each DPU struct dpu_info_t { uint32_t rows_per_dpu; uint32_t rows_per_dpu_pad; uint32_t prev_rows_dpu; }; struct dpu_info_t *dpu_info; #define NUM_LAYERS 3 #define max(x, y) (x > y ? x : y) #define min(x, y) (x < y ? x : y) // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T int32_t #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang/uPIMulator/benchmark/MLP/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int m_size; unsigned int n_size; unsigned int n_warmup; unsigned int n_reps; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -m m_size (default=2048 elements)" "\n -n n_size (default=2048 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.m_size = 163840; p.n_size = 4096; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hm:n:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'm': p.m_size = atoi(optarg); break; case 'n': p.n_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/MLP/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[5]; struct timeval stopTime[5]; double time[5]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); //printf("Time (ms): %f\t",((timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + // (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec)) / 1000); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/RED/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/RED/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 VERSION ?= SINGLE SYNC ?= HAND TYPE ?= INT64 ENERGY ?= 0 PERF ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_VERSION_$(4)_SYNC_$(5)_TYPE_$(6).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${VERSION},${SYNC},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DENERGY=${ENERGY} -DPERF=${PERF} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DPERF=${PERF} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -w 0 -e 1 -i 6553600 -x 1 ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/cpu/Makefile ================================================ all: g++ -O2 app_baseline.cpp -fopenmp -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_CPP -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP -lgomp -I/usr/local/cuda-8.0/include -lm -o red -D${TYPE} clean: rm red ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/cpu/README ================================================ Reduction (RED) Compilation instructions TYPE=UINT64 make Execution instructions ./red -i 1048576000 -t 4 ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/cpu/app_baseline.cpp ================================================ /* * JGL@SAFARI */ /** * CPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static T reduction_host(T* A, unsigned int nr_elements) { T count = 0; for (unsigned int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=2M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2 << 20; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 1; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; assert(input_size % (p.n_threads) == 0 && "Input size!"); // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; T count = 0; T count_host = 0; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::omp::vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); count_host = reduction_host(A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); thrust::omp::vector d_input(input_size); memcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T)); omp_set_num_threads(p.n_threads); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); count = thrust::reduce(thrust::omp::par, d_input.begin(), d_input.end()); if(rep >= p.n_warmup) stop(&timer, 1); h_output = d_input; } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel "); print(&timer, 1, p.n_reps); // Check output bool status = true; if(count_host != count){ status = false; printf("%lu -- %lu\n", count, count_host); } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc app_baseline.cu -I/usr/local/cuda/include -lm -o red -D${TYPE} clean: rm red ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/gpu/README ================================================ Reduction (RED) Compilation instructions TYPE=UINT64 make Execution instructions ./red -i 1048576000 ================================================ FILE: golang/uPIMulator/benchmark/RED/baselines/gpu/app_baseline.cu ================================================ /* * JGL@SAFARI */ /** * GPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static T reduction_host(T* A, unsigned int nr_elements) { T count = 0; for (unsigned int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 160 * 6553600; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties, 0); cudaSetDevice(0); struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; T count = 0; T count_host = 0; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::host_vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); count_host = reduction_host(A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; thrust::device_vector d_input(input_size); cudaMemcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T), cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); count = thrust::reduce(d_input.begin(),d_input.end()); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); time_gpu += time1; h_output = d_input; cudaEventDestroy(start); cudaEventDestroy(stop); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel (ms):"); printf("%f\n", time_gpu / p.n_reps); // Check output bool status = true; if(count_host != count){ status = false; printf("%lu -- %lu\n", count, count_host); } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/RED/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) SET(VERSION SINGLE) SET(SYNC HAND) SET(PERF 0) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/RED/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DPERF=${PERF}") file(GLOB_RECURSE SRCS *.c) add_executable(RED_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/RED/dpu/task.c ================================================ /* * Reduction with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/cyclecount.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; // Reduction in each tasklet T __attribute__ ((noinline)) reduction(T *input, unsigned int l_size){ T output = 0; for (unsigned int j = 0; j < l_size; j++){ output += input[j]; } return output; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap #if PERF perfcounter_config(COUNT_CYCLES, true); #endif } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; #if PERF && !PERF_SYNC result->cycles = 0; perfcounter_cycles cycles; timer_start(&cycles); // START TIMER #endif uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local count T l_count = 0; #if !PERF_SYNC // COMMENT OUT TO COMPARE SYNC PRIMITIVES (Experiment in Appendix) for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Reduction in each tasklet l_count += reduction(cache_A, l_size_bytes >> DIV); } #endif // Reduce local counts message[tasklet_id] = l_count; #if PERF && PERF_SYNC // TIMER FOR SYNC PRIMITIVES result->cycles = 0; perfcounter_cycles cycles; timer_start(&cycles); // START TIMER #endif #ifdef TREE // Tree-based reduction #ifdef BARRIER // Barrier barrier_wait(&my_barrier); #endif #pragma unroll for (unsigned int offset = 1; offset < NR_TASKLETS; offset <<= 1){ if((tasklet_id & (2*offset - 1)) == 0){ #ifndef BARRIER // Wait handshake_wait_for(tasklet_id + offset); #endif message[tasklet_id] += message[tasklet_id + offset]; } #ifdef BARRIER // Barrier barrier_wait(&my_barrier); #else else if ((tasklet_id & (offset - 1)) == 0){ // Ensure that wait and notify are in pair // Notify handshake_notify(); } #endif } #else // Single-thread reduction // Barrier barrier_wait(&my_barrier); if(tasklet_id == 0) #pragma unroll for (unsigned int each_tasklet = 1; each_tasklet < NR_TASKLETS; each_tasklet++){ message[0] += message[each_tasklet]; } #endif #if PERF && PERF_SYNC // TIMER FOR SYNC PRIMITIVES result->cycles = timer_stop(&cycles); // STOP TIMER #endif // Total count in this DPU if(tasklet_id == 0){ result->t_count = message[tasklet_id]; } #if PERF && !PERF_SYNC result->cycles = timer_stop(&cycles); // STOP TIMER #endif return 0; } ================================================ FILE: golang/uPIMulator/benchmark/RED/host/app.c ================================================ /** * app.c * RED Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; // Create input arrays static void read_input(T* A, unsigned int nr_elements) { srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { A[i] = (T)(rand()); } } // Compute output in the host static T reduction_host(T* A, unsigned int nr_elements) { T count = 0; for (unsigned int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; #if PERF double cc = 0; double cc_min = 0; #endif const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_8bytes = ((input_size * sizeof(T)) % 8) != 0 ? roundup(input_size, 8) : input_size; // Input size per DPU (max.), 8-byte aligned const unsigned int input_size_dpu = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_8bytes = ((input_size_dpu * sizeof(T)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); T *bufferA = A; T count = 0; T count_host = 0; // Create an input file with arbitrary data read_input(A, input_size); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); count_host = reduction_host(A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); count = 0; // Input arguments unsigned int kernel = 0; dpu_arguments_t input_arguments[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); dpu_results_t results[nr_of_dpus]; T* results_count = malloc(nr_of_dpus * sizeof(T)); if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); i = 0; // PARALLEL RETRIEVE TRANSFER dpu_results_t* results_retrieve[nr_of_dpus]; DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if(each_tasklet == 0) results[i].t_count = results_retrieve[i][each_tasklet].t_count; } #if !PERF free(results_retrieve[i]); #endif // Sequential reduction count += results[i].t_count; #if PRINT printf("i=%d -- %lu\n", i, count); #endif } #if PERF DPU_FOREACH(dpu_set, dpu, i) { results[i].cycles = 0; // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if (results_retrieve[i][each_tasklet].cycles > results[i].cycles) results[i].cycles = results_retrieve[i][each_tasklet].cycles; } free(results_retrieve[i]); } #endif if(rep >= p.n_warmup) stop(&timer, 3); #if PERF uint64_t max_cycles = 0; uint64_t min_cycles = 0xFFFFFFFFFFFFFFFF; // Print performance results if(rep >= p.n_warmup){ i = 0; DPU_FOREACH(dpu_set, dpu) { if(results[i].cycles > max_cycles) max_cycles = results[i].cycles; if(results[i].cycles < min_cycles) min_cycles = results[i].cycles; i++; } cc += (double)max_cycles; cc_min += (double)min_cycles; } #endif // Free memory free(results_count); } #if PERF printf("DPU cycles = %g cc\n", cc / p.n_reps); #endif // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("Inter-DPU "); print(&timer, 3, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; if(count != count_host) status = false; if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/RED/run.sh ================================================ #!/bin/bash for i in 1 do for j in BARRIER HAND do for k in 1 2 4 8 16 do PERF=1 NR_DPUS=$i NR_TASKLETS=$k BL=10 VERSION=TREE SYNC=$j make all wait ./bin/host_code -w 2 -e 10 -i 2097152 > profile/TREE_${j}_tl${k}_dpu${i}.txt #./bin/host_code -w 2 -e 10 -i 2048 > profile/TREE_${j}_tl${k}_dpu${i}.txt wait make clean wait done done done for i in 1 do for k in 1 2 4 8 16 do PERF=1 NR_DPUS=$i NR_TASKLETS=$k BL=10 VERSION=SINGLE make all wait ./bin/host_code -w 2 -e 10 -i 2097152 > profile/SINGLE_SINGLE_tl${k}_dpu${i}.txt #./bin/host_code -w 2 -e 10 -i 2048 > profile/SINGLE_SINGLE_tl${k}_dpu${i}.txt wait make clean wait done done ================================================ FILE: golang/uPIMulator/benchmark/RED/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; T t_count; } dpu_arguments_t; typedef struct { uint64_t cycles; T t_count; } dpu_results_t; #ifndef PERF #define PERF 0 // Use perfcounters? #endif #ifndef PERF_SYNC #define PERF_SYNC 0 // Use perfcounters to time sync primitives? #endif #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/RED/support/cyclecount.h ================================================ #include // Timer typedef struct perfcounter_cycles{ perfcounter_t start; perfcounter_t end; perfcounter_t end2; }perfcounter_cycles; void timer_start(perfcounter_cycles *cycles){ cycles->start = perfcounter_get(); // START TIMER } uint64_t timer_stop(perfcounter_cycles *cycles){ cycles->end = perfcounter_get(); // STOP TIMER cycles->end2 = perfcounter_get(); // STOP TIMER return(((uint64_t)((uint32_t)(((cycles->end >> 4) - (cycles->start >> 4)) - ((cycles->end2 >> 4) - (cycles->end >> 4))))) << 4); } ================================================ FILE: golang/uPIMulator/benchmark/RED/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=6553600 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 6553600; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/RED/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 BL ?= 10 TYPE ?= INT64 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/Makefile ================================================ all: g++ -O2 app_baseline.cpp -fopenmp -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_CPP -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP -lgomp -I/usr/local/cuda-8.0/include -lm -o scan -D${TYPE} clean: rm scan ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/README ================================================ Prefix sum (SCAN) Compilation instructions TYPE=UINT64 make Execution instructions ./scan -i 1258291200 -t 4 ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/app_baseline.cpp ================================================ /* * JGL@SAFARI */ /** * CPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i - 1]; } } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2 << 20; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.input_size; assert(input_size % (p.n_threads) == 0 && "Input size!"); // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::omp::vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); memcpy(thrust::raw_pointer_cast(&h_output[0]), A, input_size * sizeof(T)); omp_set_num_threads(p.n_threads); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); thrust::exclusive_scan(thrust::omp::par, h_output.begin(),h_output.end(),h_output.begin()); if(rep >= p.n_warmup) stop(&timer, 1); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel "); print(&timer, 1, p.n_reps); // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != h_output[i]){ status = false; //printf("%d: %lu -- %lu\n", i, C[i], h_output[i]); } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc app_baseline.cu -I/usr/local/cuda/include -lm -o scan -D${TYPE} clean: rm scan ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/README ================================================ Prefix sum (SCAN) Compilation instructions TYPE=UINT64 make Execution instructions ./scan -i 1258291200 ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/app_baseline.cu ================================================ /* * JGL@SAFARI */ /** * GPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i - 1]; } } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=640 * 3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1258291200; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties, 0); cudaSetDevice(0); struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::host_vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; thrust::device_vector d_input(input_size); cudaMemcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T), cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); thrust::exclusive_scan(d_input.begin(),d_input.end(),d_input.begin()); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); time_gpu += time1; h_output = d_input; cudaEventDestroy(start); cudaEventDestroy(stop); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel (ms):"); printf("%f\n", time_gpu / p.n_reps); // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != h_output[i]){ status = false; printf("%d: %lu -- %lu\n", i, C[i], h_output[i]); } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SCAN-RSS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(SCAN-RSS_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/dpu/task.c ================================================ /* * Scan with multiple tasklets (Reduce-scan-scan) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; T message_partial_count; // Reduction in each tasklet T __attribute__ ((noinline)) reduction(T *input){ T output = 0; #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output += input[j]; } return output; } // Scan in each tasklet T __attribute__ ((noinline)) scan(T *output, T *input){ output[0] = input[0]; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { output[j] = output[j - 1] + input[j]; } return output[REGS - 1]; } // Handshake with adjacent tasklets T __attribute__ ((noinline)) handshake_sync(T l_count, unsigned int tasklet_id){ T p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Add in each tasklet void __attribute__ ((noinline)) add_(T *output, T p_count){ #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output[j] += p_count; } } extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Reduction int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local count T l_count = 0; for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Reduction in each tasklet l_count += reduction(cache_A); } // Reduce local counts message[tasklet_id] = l_count; // Single-runtime reduction // Barrier barrier_wait(&my_barrier); if(tasklet_id == 0){ for (unsigned int each_tasklet = 1; each_tasklet < NR_TASKLETS; each_tasklet++){ message[0] += message[each_tasklet]; } // Total count in this DPU result->t_count = message[0]; } return 0; } // Scan int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = DPU_INPUT_ARGUMENTS.t_count; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Scan in each tasklet T l_count = scan(cache_B, cache_A); // Sync with adjacent tasklets T p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Add in each tasklet add_(cache_B, message_partial_count + p_count); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/host/app.c ================================================ /** * app.c * SCAN-RSS Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static T* C; static T* C2; // Create input arrays static void read_input(T* A, unsigned int nr_elements, unsigned int nr_elements_round) { srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { A[i] = (T) (rand()); } for (unsigned int i = nr_elements; i < nr_elements_round; i++) { A[i] = 0; } } // Compute output in the host static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i]; } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; T accum = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_dpu_ = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_round = (input_size_dpu_ % (NR_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NR_TASKLETS * REGS)) : input_size_dpu_; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data read_input(A, input_size, input_size_dpu_round * nr_of_dpus); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments const unsigned int input_size_dpu = input_size_dpu_round; unsigned int kernel = 0; dpu_arguments_t input_arguments = {input_size_dpu * sizeof(T), kernel, 0}; // Copy input arrays i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferA + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); dpu_results_t results[nr_of_dpus]; T* results_scan = malloc(nr_of_dpus * sizeof(T)); i = 0; accum = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER dpu_results_t* results_retrieve[nr_of_dpus]; DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if(each_tasklet == 0) results[i].t_count = results_retrieve[i][each_tasklet].t_count; } free(results_retrieve[i]); // Sequential scan T temp = results[i].t_count; results_scan[i] = accum; accum += temp; #if PRINT printf("i=%d -- %lu, %lu, %lu\n", i, results_scan[i], accum, temp); #endif } // Arguments for scan kernel (2nd kernel) kernel = 1; dpu_arguments_t input_arguments_2[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 3); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 4, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 4); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); if(rep >= p.n_warmup) start(&timer, 5, rep - p.n_warmup); i = 0; // PARALLEL RETRIEVE TRANSFER DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferC + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(T), input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 5); // Free memory free(results_scan); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel Reduction "); print(&timer, 2, p.n_reps); printf("Inter-DPU (Scan) "); print(&timer, 3, p.n_reps); printf("DPU Kernel Scan "); print(&timer, 4, p.n_reps); printf("DPU-CPU "); print(&timer, 5, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != bufferC[i]){ status = false; #if PRINT printf("%d: %lu -- %lu\n", i, C[i], bufferC[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/run.sh ================================================ #!/bin/bash for i in 2048 4096 8192 16384 65536 262144 1048576 3932160 do NR_DPUS=1 NR_TASKLETS=16 BL=10 VERSION=SINGLE make all wait ./bin/host_code -w 10 -e 100 -i ${i} > profile/out${i}_tl16_bl10_dpu11 wait make clean wait done ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif #define REGS (BLOCK_SIZE >> DIV) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; T t_count; } dpu_arguments_t; typedef struct { T t_count; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/SCAN-RSS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 BL ?= 10 TYPE ?= INT64 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SCAN-SSA/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(SCAN-SSA_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/dpu/task.c ================================================ /* * Scan with multiple tasklets (Scan-scan-add) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; T message_partial_count; // Scan in each tasklet T __attribute__ ((noinline)) scan(T *output, T *input){ output[0] = input[0]; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { output[j] = output[j - 1] + input[j]; } return output[REGS - 1]; } // Handshake with adjacent tasklets T __attribute__ ((noinline)) handshake_sync(T l_count, unsigned int tasklet_id){ T p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Add in each tasklet void __attribute__ ((noinline)) add_(T *output, T p_count){ #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output[j] += p_count; } } extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Scan-(handshake)scan int main_kernel1() { #if 1 // Comment out for appendix experiment unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = DPU_INPUT_ARGUMENTS.t_count; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Scan in each tasklet T l_count = scan(cache_B, cache_A); // Sync with adjacent tasklets T p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Add in each tasklet add_(cache_B, message_partial_count + p_count); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } #endif return 0; } // Add int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T t_count = DPU_INPUT_ARGUMENTS.t_count; for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_B + byte_index), cache_A, BLOCK_SIZE); // Add in each tasklet add_(cache_A, t_count); // Write cache to current MRAM block mram_write(cache_A, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/host/app.c ================================================ /** * app.c * SCAN-SSA Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static T* C; static T* C2; // Create input arrays static void read_input(T* A, unsigned int nr_elements, unsigned int nr_elements_round) { srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { A[i] = (T) (rand()); } for (unsigned int i = nr_elements; i < nr_elements_round; i++) { A[i] = 0; } } // Compute output in the host static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i]; } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; T accum = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_dpu_ = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_round = (input_size_dpu_ % (NR_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NR_TASKLETS * REGS)) : input_size_dpu_; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data read_input(A, input_size, input_size_dpu_round * nr_of_dpus); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments const unsigned int input_size_dpu = input_size_dpu_round; unsigned int kernel = 0; dpu_arguments_t input_arguments = {input_size_dpu * sizeof(T), kernel, 0}; // Copy input arrays i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferA + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); dpu_results_t results[nr_of_dpus]; T* results_scan = malloc(nr_of_dpus * sizeof(T)); i = 0; accum = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER dpu_results_t* results_retrieve[nr_of_dpus]; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if(each_tasklet == NR_TASKLETS - 1) results[i].t_count = results_retrieve[i][each_tasklet].t_count; } free(results_retrieve[i]); // Sequential scan T temp = results[i].t_count; results_scan[i] = accum; accum += temp; #if PRINT printf("i=%d -- %lu, %lu, %lu\n", i, results_scan[i], accum, temp); #endif } // Arguments for add kernel (2nd kernel) kernel = 1; dpu_arguments_t input_arguments_2[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 3); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 4, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 4); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); if(rep >= p.n_warmup) start(&timer, 5, rep - p.n_warmup); i = 0; // PARALLEL RETRIEVE TRANSFER DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferC + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(T), input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 5); // Free memory free(results_scan); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel Scan "); print(&timer, 2, p.n_reps); printf("Inter-DPU (Scan) "); print(&timer, 3, p.n_reps); printf("DPU Kernel Add "); print(&timer, 4, p.n_reps); printf("DPU-CPU "); print(&timer, 5, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != bufferC[i]){ status = false; #if PRINT printf("%d: %lu -- %lu\n", i, C[i], bufferC[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/run.sh ================================================ #!/bin/bash for i in 2048 4096 8192 16384 65536 262144 1048576 3932160 do NR_DPUS=1 NR_TASKLETS=16 BL=10 make all wait ./bin/host_code -w 10 -e 100 -i ${i} > profile/out${i}_tl16_bl10_dpu11 wait make clean wait done ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif #define REGS (BLOCK_SIZE >> DIV) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; T t_count; } dpu_arguments_t; typedef struct { T t_count; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/SCAN-SSA/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/SEL/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/SEL/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/cpu/Makefile ================================================ all: gcc -o sel -fopenmp app_baseline.c clean: rm sel ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/cpu/README ================================================ Select (SEL) Compilation instructions make Execution instructions ./sel -i 1258291200 -t 4 Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/cpu/app_baseline.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" static uint64_t *A; static uint64_t *B; static uint64_t *C; static uint64_t *C2; static int pos; bool pred(const uint64_t x){ return (x % 2) == 0; } void *create_test_file(unsigned int nr_elements) { //srand(0); A = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); B = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); C = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); printf("nr_elements\t%u\t", nr_elements); for (int i = 0; i < nr_elements; i++) { //A[i] = (unsigned int) (rand()); A[i] = i+1; B[i] = 0; } } /** * @brief compute output in the host */ static int select_host(int size, int t) { pos = 0; C[pos] = A[pos]; omp_set_num_threads(t); #pragma omp parallel for for(int my = 1; my < size; my++) { if(!pred(A[my])) { int p; #pragma omp atomic update pos++; p = pos; C[p] = A[my]; } } return pos; } // Params --------------------------------------------------------------------- typedef struct Params { char* dpu_type; int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d DPU type (default=fsim)" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=2)" "\n -e # of timed repetition iterations (default=5)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16 << 20; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 5; int opt; while((opt = getopt(argc, argv, "hi:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; uint32_t accum = 0; int total_count; // Create an input file with arbitrary data. create_test_file(file_size); Timer timer; start(&timer, 0, 0); total_count = select_host(file_size, p.n_threads); stop(&timer, 0); printf("Total count = %d\t", total_count); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc select.cu -I/usr/local/cuda/include -lm -o select -D COARSENING=32 -D THREADS=512 -D INT64 clean: rm select ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/gpu/README ================================================ Select (SEL) Compilation instructions make Execution instructions ./select 0 50 1258291200 Compilation flags FLOAT - For single precision arrays (Default: Double precision) INT - For integer arrays (Note: Sample predicate is only for INT) THREADS - Thread block size (Default: 1024) COARSENING - Coarsening factor (Default: 16 (SP and INT); 8 (DP)) ATOMIC - Global atomics for synchronization (Default: No atomics) Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/gpu/ds.h ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include #include #include #include #include #include #include #include #ifdef FLOAT #define T float #elif INT #define T int #elif INT64 #define T int64_t #else #define T double #endif #ifdef THREADS #define L_DIM THREADS #else #define L_DIM 1024 #endif #ifdef COARSENING #define REGS COARSENING #else #ifdef FLOAT #define REGS 16 #elif INT #define REGS 16 #else #define REGS 8 #endif #endif #ifdef ATOMIC #define ATOM 1 #else #define ATOM 0 #endif #define WARP_SIZE 32 #define PRINT 0 // Dynamic allocation of runtime workgroup id __device__ int dynamic_wg_id(volatile unsigned int *flags, const int num_flags){ __shared__ int gid_; if (threadIdx.x == 0) gid_ = atomicAdd((unsigned int*)&flags[num_flags + 1], 1); __syncthreads(); int my_s = gid_; return my_s; } // Set global synchronization (regular DS) __device__ void ds_sync(volatile unsigned int *flags, const int my_s){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} atomicOr((unsigned int*)&flags[my_s + 1], 1); } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} flags[my_s + 1] = 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS) __device__ void ds_sync_irregular(volatile unsigned int *flags, const int my_s, int *count){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} int flag = flags[my_s]; atomicAdd((unsigned int*)&flags[my_s + 1], flag + *count); *count = flag - 1; } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} int flag = flags[my_s]; flags[my_s + 1] = flag + *count; *count = flag - 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS Partition) __device__ void ds_sync_irregular_partition(volatile unsigned int *flags1, volatile unsigned int *flags2, const int my_s, int *count1, int *count2){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags1[my_s], 0) == 0){} int flag2 = flags2[my_s]; atomicAdd((unsigned int*)&flags2[my_s + 1], flag2 + *count); int flag1 = flags1[my_s]; atomicAdd((unsigned int*)&flags1[my_s + 1], flag1 + *count); *count1 = flag1 - 1; *count2 = flag2 - 1; } #else if (threadIdx.x == 0){ while (flags1[my_s] == 0){} int flag2 = flags2[my_s]; flags2[my_s + 1] = flag2 + *count2; int flag1 = flags1[my_s]; flags1[my_s + 1] = flag1 + *count1; *count1 = flag1 - 1; *count2 = flag2 - 1; } #endif __syncthreads(); } // Reduction kernel (CUDA SDK reduce6) template __device__ void reduction(S *count, S local_cnt){ __shared__ S sdata[L_DIM]; unsigned int tid = threadIdx.x; S mySum = local_cnt; // each runtime puts its local sum into shared memory sdata[tid] = local_cnt; __syncthreads(); // do reduction in shared mem if ((blockDim.x >= 1024) && (tid < 512)){ sdata[tid] = mySum = mySum + sdata[tid + 512]; } __syncthreads(); if ((blockDim.x >= 512) && (tid < 256)){ sdata[tid] = mySum = mySum + sdata[tid + 256]; } __syncthreads(); if ((blockDim.x >= 256) && (tid < 128)){ sdata[tid] = mySum = mySum + sdata[tid + 128]; } __syncthreads(); if ((blockDim.x >= 128) && (tid < 64)){ sdata[tid] = mySum = mySum + sdata[tid + 64]; } __syncthreads(); #if (__CUDA_ARCH__ >= 300 ) if ( tid < 32 ){ // Fetch final intermediate sum from 2nd warp if (blockDim.x >= 64) mySum += sdata[tid + 32]; // Reduce final warp using shuffle #pragma unroll for (int offset = WARP_SIZE/2; offset > 0; offset /= 2){ //mySum += __shfl_down(mySum, offset); mySum += __shfl_xor(mySum, offset); } } #else // fully unroll reduction within a single warp if ((blockDim.x >= 64) && (tid < 32)){ sdata[tid] = mySum = mySum + sdata[tid + 32]; } __syncthreads(); if ((blockDim.x >= 32) && (tid < 16)){ sdata[tid] = mySum = mySum + sdata[tid + 16]; } __syncthreads(); if ((blockDim.x >= 16) && (tid < 8)){ sdata[tid] = mySum = mySum + sdata[tid + 8]; } __syncthreads(); if ((blockDim.x >= 8) && (tid < 4)){ sdata[tid] = mySum = mySum + sdata[tid + 4]; } __syncthreads(); if ((blockDim.x >= 4) && (tid < 2)){ sdata[tid] = mySum = mySum + sdata[tid + 2]; } __syncthreads(); if ((blockDim.x >= 2) && ( tid < 1)){ sdata[tid] = mySum = mySum + sdata[tid + 1]; } __syncthreads(); #endif // write result for this block to global mem if (tid == 0) *count = mySum; } // Binary prefix-sum (GPU Computing Gems) __device__ inline int lane_id(void) { return threadIdx.x % WARP_SIZE; } __device__ inline int warp_id(void) { return threadIdx.x / WARP_SIZE; } __device__ unsigned int warp_prefix_sums(bool p){ unsigned int b = __ballot(p); return __popc(b & ((1 << lane_id()) - 1)); } __device__ int warp_scan(int val, volatile int *s_data){ #if (__CUDA_ARCH__ < 300 ) int idx = 2 * threadIdx.x - (threadIdx.x & (WARP_SIZE - 1)); s_data[idx] = 0; idx += WARP_SIZE; int t = s_data[idx] = val; s_data[idx] = t = t + s_data[idx - 1]; s_data[idx] = t = t + s_data[idx - 2]; s_data[idx] = t = t + s_data[idx - 4]; s_data[idx] = t = t + s_data[idx - 8]; s_data[idx] = t = t + s_data[idx - 16]; return s_data[idx - 1]; #else int x = val; #pragma unroll for(int offset = 1; offset < 32; offset <<= 1){ // From GTC: Kepler shuffle tips and tricks: #if 0 int y = __shfl_up(x, offset); if(lane_id() >= offset) x += y; #else asm volatile("{" " .reg .s32 r0;" " .reg .pred p;" " shfl.up.b32 r0|p, %0, %1, 0x0;" " @p add.s32 r0, r0, %0;" " mov.s32 %0, r0;" "}" : "+r"(x) : "r"(offset)); #endif } return x - val; #endif } __device__ int block_binary_prefix_sums(int* count, int x){ __shared__ int sdata[L_DIM]; // A. Exclusive scan within each warp int warpPrefix = warp_prefix_sums(x); // B. Store in shared memory if(lane_id() == WARP_SIZE - 1) sdata[warp_id()] = warpPrefix + x; __syncthreads(); // C. One warp scans in shared memory if(threadIdx.x < WARP_SIZE) sdata[threadIdx.x] = warp_scan(sdata[threadIdx.x], sdata); __syncthreads(); // D. Each runtime calculates it final value int thread_out_element = warpPrefix + sdata[warp_id()]; int output = thread_out_element + *count; __syncthreads(); if(threadIdx.x == blockDim.x - 1) *count += (thread_out_element + x); return output; } ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/gpu/kernel.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ __global__ void select_remove_if(T *matrix_out, T *matrix, int size, volatile unsigned int *flags, struct is_even pred) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(!pred(reg[j])) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } __global__ void select_copy_if(T *matrix_out, T *matrix, int size, volatile unsigned int *flags, struct is_even pred) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(pred(reg[j])) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } ================================================ FILE: golang/uPIMulator/benchmark/SEL/baselines/gpu/select.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include "ds.h" // Sample predicate for partition (only for INT) struct is_even{ __host__ __device__ bool operator()(const T &x){ return (x % 2) == 0; } }; #include "kernel.cu" // Sequential CPU version void cpu_copy_if(T* output, T* input, int elements, struct is_even pred){ int pos = 0; for (int i = 0; i < elements; i++){ if(pred(input[i])){ output[pos] = input[i]; pos++; } } } void cpu_remove_if(T* input, int elements, struct is_even pred){ int pos = 0; for (int i = 0; i < elements; i++){ if(!pred(input[i])){ input[pos] = input[i]; pos++; } } } int main(int argc, char **argv){ // Syntax verification if (argc != 4) { printf("Wrong format\n"); printf("Syntax: %s \n",argv[0]); exit(1); } int device = atoi(argv[1]); int input = atoi(argv[2]); int numElements = atoi(argv[3]); size_t size = numElements * sizeof(T); // Set device cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties,device); cudaSetDevice(device); printf("DS Select on %s\n", device_properties.name); printf("Thread block size = %d\n", L_DIM); printf("Coarsening factor = %d\n", REGS); #ifdef FLOAT printf("Single precision array: %d elements\n", numElements); #elif INT printf("Integer array: %d elements\n", numElements); #else printf("Double precision array: %d elements\n", numElements); #endif // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; float time3 = 0; // Allocate the host input vector A T *h_A = (T*)malloc(size); // Allocate the host output vectors T *h_B = (T*)malloc(size); T *h_C = (T*)malloc(size); T *h_D = (T*)malloc(size); // Allocate the device input vector A and output vector B T *d_A = NULL; cudaMalloc((void **)&d_A, size); T *d_B = NULL; cudaMalloc((void **)&d_B, size); #define WARMUP 2 #define REP 10 unsigned int flagM1 = 0; unsigned int flagM2 = 0; for(int iteration = 0; iteration < REP+WARMUP; iteration++){ // Initialize the host input vectors srand(2014); for(int i = 0; i < numElements; i++) h_A[i] = i % 2 != 0 ? i:i+1; int M = (numElements * input)/100; int m = M; while(m>0){ int x = (int)(numElements*(((float)rand()/(float)RAND_MAX))); if(h_A[x] % 2 != 0){ h_A[x] = x * 2; m--; } } #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_A+i)); } printf("\n"); #endif // Copy the host input vector A in host memory to the device input vector in device memory cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); int ldim = L_DIM; // Atomic flags unsigned int* d_flags = NULL; const int num_flags = numElements % (ldim * REGS) == 0 ? numElements / (ldim * REGS) : numElements / (ldim * REGS) + 1; unsigned int *flags = (unsigned int *)calloc(sizeof(unsigned int), num_flags + 2); flags[0] = 1; flags[num_flags + 1] = 0; cudaMalloc((void **)&d_flags, (num_flags + 2) * sizeof(unsigned int)); cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); // Number of work-groups/runtime blocks int num_wg = num_flags; // Start timer cudaEventRecord( start, 0 ); // Kernel launch (Copy_if) select_copy_if<<>>(d_B, d_A, numElements, d_flags, is_even()); cudaMemcpy(&flagM1, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // Stop timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time2 += time1; if(iteration == REP+WARMUP-1){ float timer = time2 / REP; double bw = (double)((numElements + flagM1) * sizeof(T)) / (double)(timer * 1000000.0); printf("Copy_if - Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Atomic flags cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); free(flags); // Start timer cudaEventRecord( start, 0 ); // Kernel launch (Remove_if) select_remove_if<<>>(d_A, d_A, numElements, d_flags, is_even()); cudaMemcpy(&flagM2, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time3 += time1; if(iteration == REP+WARMUP-1){ float timer = time3 / REP; double bw = (double)((numElements + flagM2) * sizeof(T)) / (double)(timer * 1000000.0); printf("Remove_if - Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Free flags cudaFree(d_flags); } // Copy to host memory cudaMemcpy(h_B, d_B, size, cudaMemcpyDeviceToHost); cudaMemcpy(h_C, d_A, size, cudaMemcpyDeviceToHost); // CPU execution for comparison cpu_copy_if(h_D, h_A, numElements, is_even()); cpu_remove_if(h_A, numElements, is_even()); // Verify that the result vector is correct #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_B+i)); } printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_D+i)); } printf("\n"); #endif for (int i = 0; i < flagM1 - 1; ++i){ if (h_B[i] != h_D[i]){ fprintf(stderr, "Copy_if - Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } for (int i = 0; i < flagM2 - 1; ++i){ if (h_C[i] != h_A[i]){ fprintf(stderr, "Remove_if - Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } printf("Test PASSED\n"); // Free device global memory cudaFree(d_A); cudaFree(d_B); cudaEventDestroy(start); cudaEventDestroy(stop); // Free host memory free(h_A); free(h_B); free(h_C); free(h_D); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SEL/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SEL/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(SEL_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/SEL/dpu/task.c ================================================ /* * Select with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets uint32_t message[NR_TASKLETS]; uint32_t message_partial_count; // SEL in each tasklet unsigned int __attribute__ ((noinline)) select(T *output, T *input){ unsigned int pos = 0; #pragma unroll for(unsigned int j = 0; j < REGS; j++) { if(!pred(input[j])) { output[pos] = input[j]; pos++; } } return pos; } // Handshake with adjacent tasklets unsigned int __attribute__ ((noinline)) handshake_sync(unsigned int l_count, unsigned int tasklet_id){ unsigned int p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = 0; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // SELECT in each tasklet uint32_t l_count = select(cache_B, cache_A); // In-place or out-of-place? // Sync with adjacent tasklets uint32_t p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + (message_partial_count + p_count) * sizeof(T)), l_count * sizeof(T)); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/SEL/host/app.c ================================================ /** * app.c * SEL Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static T* C; static T* C2; // Create input arrays static void read_input(T* A, unsigned int nr_elements, unsigned int nr_elements_round) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()); A[i] = i + 1; } for (unsigned int i = nr_elements; i < nr_elements_round; i++) { // Complete with removable elements A[i] = 0; } } // Compute output in the host static unsigned int select_host(T* C, T* A, unsigned int nr_elements) { unsigned int pos = 0; for (unsigned int i = 0; i < nr_elements; i++) { if(!pred(A[i])) { C[pos] = A[i]; pos++; } } return pos; } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; uint32_t accum = 0; uint32_t total_count = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_dpu_ = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_round = (input_size_dpu_ % (NR_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NR_TASKLETS * REGS)) : input_size_dpu_; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data read_input(A, input_size, input_size_dpu_round * nr_of_dpus); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); total_count = select_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments const unsigned int input_size_dpu = input_size_dpu_round; unsigned int kernel = 0; dpu_arguments_t input_arguments = {input_size_dpu * sizeof(T), kernel}; // Copy input arrays i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferA + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); dpu_results_t results[nr_of_dpus]; uint32_t* results_scan = malloc(nr_of_dpus * sizeof(uint32_t)); i = 0; accum = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER dpu_results_t* results_retrieve[nr_of_dpus]; DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { // Count of this DPU if(each_tasklet == NR_TASKLETS - 1){ results[i].t_count = results_retrieve[i][each_tasklet].t_count; } } // Sequential scan uint32_t temp = results[i].t_count; results_scan[i] = accum; accum += temp; #if PRINT printf("i=%d -- %u, %u, %u\n", i, results_scan[i], accum, temp); #endif free(results_retrieve[i]); } if(rep >= p.n_warmup) stop(&timer, 3); i = 0; if(rep >= p.n_warmup) start(&timer, 4, rep - p.n_warmup); DPU_FOREACH (dpu_set, dpu) { // Copy output array DPU_ASSERT(dpu_copy_from(dpu, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(T), bufferC + results_scan[i], results[i].t_count * sizeof(T))); i++; } if(rep >= p.n_warmup) stop(&timer, 4); // Free memory free(results_scan); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("Inter-DPU "); print(&timer, 3, p.n_reps); printf("DPU-CPU "); print(&timer, 4, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; if(accum != total_count) status = false; for (i = 0; i < accum; i++) { if(C[i] != bufferC[i]){ status = false; #if PRINT printf("%d: %lu -- %lu\n", i, C[i], bufferC[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/SEL/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; typedef struct { uint32_t t_count; } dpu_results_t; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint64_t #define REGS (BLOCK_SIZE >> 3) // 64 bits // Sample predicate bool pred(const T x){ return (x % 2) == 0; } #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/SEL/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/SEL/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/TRNS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=g++ CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -lm -pthread DEP=kernel.cpp kernel.h main.cpp support/common.h support/setup.h support/timer.h SRC=main.cpp kernel.cpp EXE=trns all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/README ================================================ In-place matrix transposition (TRNS) Compilation instructions make Execution instructions ./trns -w 0 -r 1 -m 16 -n 8 -o 4096 -p 2556 For more options ./trns -h Read more J. Gomez-Luna et al., “In-place Matrix Transposition on GPUs,” IEEE TPDS, 2016. ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/kernel.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "kernel.h" #include #include #include #include // CPU threads----------------------------------------------------------------- void run_cpu_threads_100(T *input, std::atomic_int *finished, std::atomic_int *head, int A, int B, int b, int threads) { ///////////////// Run CPU worker threads ///////////////////////////////// #if PRINT printf("Starting %d CPU threads\n", threads); #endif std::vector cpu_threads; for(int i = 0; i < threads; i++) { cpu_threads.push_back(std::thread([=]() { T data[b]; T backup[b]; int done; int m = A * B - 1; // Dynamic fetch int gid = (head)->fetch_add(1); while(gid < m) { int next_in_cycle = (gid * A) - m * (gid / B); if(next_in_cycle == gid) { // Dynamic fetch gid = (head)->fetch_add(1); continue; } for(int i = 0; i < b; i++) { data[i] = input[gid * b + i]; } //make sure the read is not cached done = (finished + gid)->load(); for(; done == 0; next_in_cycle = (next_in_cycle * A) - m * (next_in_cycle / B)) { for(int i = 0; i < b; i++) { backup[i] = input[next_in_cycle * b + i]; } done = (finished + next_in_cycle)->exchange(1); if(!done) { for(int i = 0; i < b; i++) { input[next_in_cycle * b + i] = data[i]; } } for(int i = 0; i < b; i++) { data[i] = backup[i]; } } // Dynamic fetch gid = (head)->fetch_add(1); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } // CPU threads----------------------------------------------------------------- void run_cpu_threads_010(T *input, std::atomic_int* head, int a, int b, int tiles, int threads) { ///////////////// Run CPU worker threads ///////////////////////////////// #if PRINT printf("Starting %d CPU threads\n", threads); #endif std::vector cpu_threads; for(int i = 0; i < threads; i++) { cpu_threads.push_back(std::thread([=]() { T tile[a * b]; int m = a * b - 1; // Dynamic fetch int gid = (head)->fetch_add(1); while(gid < tiles) { T* input_array = input + a * b * gid; for (int j = 0; j < a * b; j++) { int next = (j * a)-m*(j/b); tile[next] = input_array[j]; } for (int j = 0; j < a * b; j++) { input_array[j] = tile[j]; } // Dynamic fetch gid = (head)->fetch_add(1); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include "support/common.h" void run_cpu_threads_100(T *input, std::atomic_int *finished, std::atomic_int *head, int A, int B, int b, int threads); void run_cpu_threads_010(T *input, std::atomic_int *head, int m, int n, int tiles, int threads); ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include #include // Params --------------------------------------------------------------------- struct Params { int n_threads; int n_warmup; int n_reps; int M_; int m; int N_; int n; Params(int argc, char **argv) { n_threads = 4; n_warmup = 5; n_reps = 50; M_ = 128; m = 16; N_ = 128; n = 8; int opt; while((opt = getopt(argc, argv, "ht:w:r:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'n': n = atoi(optarg); break; case 'o': M_ = atoi(optarg); break; case 'p': N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } } void usage() { fprintf(stderr, "\nUsage: ./trns [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of host threads (default=4)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n TRNS only supports CPU-only or GPU-only execution" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=128 elements)" "\n -p N_ (default=128 elements)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(T *x_vector, const Params &p) { int in_size = p.M_ * p.m * p.N_ * p.n; srand(5432); for(int i = 0; i < in_size; i++) { x_vector[i] = ((T)(rand() % 100) / 100); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { const Params p(argc, argv); Timer timer; // Allocate timer.start("Allocation"); int M_ = p.M_; int m = p.m; int N_ = p.N_; int n = p.n; int in_size = M_ * m * N_ * n; int finished_size = M_ * m * N_; T * h_in_out = (T *)malloc(in_size * sizeof(T)); std::atomic_int *h_finished = (std::atomic_int *)malloc(sizeof(std::atomic_int) * finished_size); std::atomic_int *h_head = (std::atomic_int *)malloc(N_ * sizeof(std::atomic_int)); ALLOC_ERR(h_in_out, h_finished, h_head); T *h_in_backup = (T *)malloc(in_size * sizeof(T)); ALLOC_ERR(h_in_backup); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); read_input(h_in_out, p); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); timer.stop("Initialization"); timer.print("Initialization", 1); memcpy(h_in_backup, h_in_out, in_size * sizeof(T)); // Backup for reuse across iterations // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset memcpy(h_in_out, h_in_backup, in_size * sizeof(T)); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 1"); // Launch CPU threads std::thread main_thread_1(run_cpu_threads_100, h_in_out, h_finished, h_head, M_ * m, N_, n, p.n_threads); //M_ * m * N_); main_thread_1.join(); // end timer if(rep >= p.n_warmup) timer.stop("Step 1"); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 2"); // Launch CPU threads std::thread main_thread_2(run_cpu_threads_010, h_in_out, h_head, m, n, M_ * N_, p.n_threads); main_thread_2.join(); // end timer if(rep >= p.n_warmup) timer.stop("Step 2"); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 3"); // Launch CPU threads for(int i = 0; i < N_; i++){ std::thread main_thread_3(run_cpu_threads_100, h_in_out + i * M_ * n * m, h_finished + i * M_ * n, h_head + i, M_, n, m, p.n_threads); //M_ * n); main_thread_3.join(); } // end timer if(rep >= p.n_warmup) timer.stop("Step 3"); } timer.print("Step 1", p.n_reps); timer.print("Step 2", p.n_reps); timer.print("Step 3", p.n_reps); // Verify answer //verify(h_in_out, h_in_backup, M_ * m, N_ * n, 1); // Free memory timer.start("Deallocation"); free(h_in_out); free(h_finished); free(h_head); free(h_in_backup); timer.stop("Deallocation"); timer.print("Deallocation", 1); printf("Test Passed\n"); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #ifndef DOUBLE_PRECISION #define DOUBLE_PRECISION 1 #endif #if DOUBLE_PRECISION #define T double #else #define T float #endif #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/support/setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { time[name] = 0.0; } gettimeofday(&startTime[name], NULL); } void stop(string name) { gettimeofday(&stopTime[name], NULL); time[name] += (stopTime[name].tv_sec - startTime[name].tv_sec) * 1000000.0 + (stopTime[name].tv_usec - startTime[name].tv_usec); } void print(string name, int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / (1000 * REP)); } }; ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/cpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include inline int compare_output(T *output, T *ref, int dim) { int i; for(i = 0; i < dim; i++) { T diff = fabs(ref[i] - output[i]); if((diff - 0.0f) > 0.00001f && diff > 0.01 * fabs(ref[i])) { printf("line: %d ref: %f actual: %f diff: %f\n", i, ref[i], output[i], diff); exit(EXIT_FAILURE); } } return 0; } // Sequential transposition for comparison purposes //[w][h/t][t] to [h/t][w][t] static void trns_host(T* input, unsigned int A, unsigned int B, unsigned int b){ T* output = (T*) malloc(sizeof(T) * A * B * b); unsigned int next; for (unsigned int j = 0; j < b; j++){ for (unsigned int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (unsigned int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } inline void verify(T *input2, T *input, int height, int width, int tile_size) { trns_host(input, height, width, tile_size); compare_output(input2, input, height * width); } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=/usr/local/cuda/bin/nvcc CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -L$/usr/local/cuda/lib64/ -lm INC=-I/usr/local/cuda/include/ DEP=kernel.h main.cpp kernel.cu support/common.h support/cuda-setup.h support/timer.h support/verify.h SRC=main.cpp kernel.cu EXE=trns all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) $(INC) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/README ================================================ In-place matrix transposition (TRNS) Compilation instructions make Execution instructions ./trns -w 0 -r 1 -m 16 -n 8 -o 4096 -p 2556 -i 64 For more options ./trns -h Read more J. Gomez-Luna et al., “In-place Matrix Transposition on GPUs,” IEEE TPDS, 2016. ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/kernel.cu ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/common.h" extern __shared__ int l_mem[]; // GPU kernel ------------------------------------------------------------------------------------------ __global__ void PTTWAC_soa_asta(int A, int B, int b, T *input, int *finished, int *head) { int* done = l_mem; int* gid_ = &done[1]; const int tid = threadIdx.x; int m = A * B - 1; if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); while(gid_[0] < m) { int next_in_cycle = (gid_[0] * A) - m * (gid_[0] / B); if(next_in_cycle == gid_[0]) { if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); continue; } T data1, data2, data3, data4; int i = tid; if(i < b) data1 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data2 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data3 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data4 = input[gid_[0] * b + i]; if(tid == 0) { //make sure the read is not cached done[0] = atomicAdd(&finished[gid_[0]], 0); } __syncthreads(); for(; done[0] == 0; next_in_cycle = (next_in_cycle * A) - m * (next_in_cycle / B)) { T backup1, backup2, backup3, backup4; i = tid; if(i < b) backup1 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup2 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup3 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup4 = input[next_in_cycle * b + i]; if(tid == 0) { done[0] = atomicExch(&finished[next_in_cycle], (int)1); } __syncthreads(); if(!done[0]) { i = tid; if(i < b) input[next_in_cycle * b + i] = data1; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data2; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data3; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data4; } i = tid; if(i < b) data1 = backup1; i += blockDim.x; if(i < b) data2 = backup2; i += blockDim.x; if(i < b) data3 = backup3; i += blockDim.x; if(i < b) data4 = backup4; } if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); } } cudaError_t call_PTTWAC_soa_asta(int blocks, int threads, int A, int B, int b, T *input, int *finished, int *head, int l_mem_size){ dim3 dimGrid(blocks); dim3 dimBlock(threads); PTTWAC_soa_asta<<>>(A, B, b, input, finished, head); cudaError_t err = cudaGetLastError(); return err; } __global__ void BS_marshal(T *input, int tile_size, int width) { T* tile = (T*)l_mem; int tidx = threadIdx.x; int m = width*tile_size-1; int bid = blockIdx.x; input += tile_size*width*bid; for (int i = tidx; i < tile_size*width; i+=blockDim.x) { int next = (i * tile_size)-m*(i/width); tile[next] = input[i]; } __syncthreads(); for (int i = tidx; i < tile_size*width; i+=blockDim.x) { input[i] = tile[i]; } } cudaError_t call_BS_marshal(int blocks, int threads, int m, int n, T *input, int l_mem_size){ dim3 dimGrid(blocks); dim3 dimBlock(threads); BS_marshal<<>>(input, m, n); cudaError_t err = cudaGetLastError(); return err; } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "cuda_runtime.h" #include #include #include "support/common.h" cudaError_t call_PTTWAC_soa_asta(int blocks, int threads, int A, int B, int b, T *input, int *finished, int *head, int l_mem_size); cudaError_t call_BS_marshal(int blocks, int threads, int m, int n, T *input, int l_mem_size); ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/cuda-setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include #include // Params --------------------------------------------------------------------- struct Params { int device; int n_gpu_threads; int n_gpu_blocks; int n_threads; int n_warmup; int n_reps; int M_; int m; int N_; int n; Params(int argc, char **argv) { device = 0; n_gpu_threads = 64; n_gpu_blocks = 16; n_warmup = 5; n_reps = 50; M_ = 128; m = 16; N_ = 128; n = 8; int opt; while((opt = getopt(argc, argv, "hd:i:g:t:w:r:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': device = atoi(optarg); break; case 'i': n_gpu_threads = atoi(optarg); break; case 'g': n_gpu_blocks = atoi(optarg); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'n': n = atoi(optarg); break; case 'o': M_ = atoi(optarg); break; case 'p': N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert((n_gpu_threads > 0 && n_gpu_blocks > 0) && "TRNS only runs on CPU-only or GPU-only: './trns -g 0' or './trns -t 0'"); } void usage() { fprintf(stderr, "\nUsage: ./trns [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d CUDA device ID (default=0)" "\n -i # of device threads per block (default=64)" "\n -g # of device blocks (default=16)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n TRNS only supports CPU-only or GPU-only execution" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=128 elements)" "\n -p N_ (default=128 elements)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(T *x_vector, const Params &p) { int in_size = p.M_ * p.m * p.N_ * p.n; srand(5432); for(int i = 0; i < in_size; i++) { x_vector[i] = ((T)(rand() % 100) / 100); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { const Params p(argc, argv); CUDASetup setcuda(p.device); Timer timer; cudaError_t cudaStatus; // Allocate timer.start("Allocation"); int M_ = p.M_; int m = p.m; int N_ = p.N_; int n = p.n; int in_size = M_ * m * N_ * n; int finished_size = M_ * m * N_; T * h_in_out = (T *)malloc(in_size * sizeof(T)); std::atomic_int *h_finished = (std::atomic_int *)malloc(sizeof(std::atomic_int) * finished_size); std::atomic_int *h_head = (std::atomic_int *)malloc(N_ * sizeof(std::atomic_int)); ALLOC_ERR(h_in_out, h_finished, h_head); T * d_in_out; int * d_finished; int * d_head; if(p.n_gpu_blocks != 0) { cudaStatus = cudaMalloc((void**)&d_in_out, in_size * sizeof(T)); cudaStatus = cudaMalloc((void**)&d_finished, (p.n_gpu_blocks != 0) ? sizeof(int) * finished_size : 0); cudaStatus = cudaMalloc((void**)&d_head, (p.n_gpu_blocks != 0) ? N_ * sizeof(int) : 0); CUDA_ERR(); } T *h_in_backup = (T *)malloc(in_size * sizeof(T)); ALLOC_ERR(h_in_backup); cudaDeviceSynchronize(); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); const int max_gpu_threads = setcuda.max_gpu_threads(); read_input(h_in_out, p); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); timer.stop("Initialization"); timer.print("Initialization", 1); memcpy(h_in_backup, h_in_out, in_size * sizeof(T)); // Backup for reuse across iterations // Copy to device timer.start("Copy To Device"); if(p.n_gpu_blocks != 0) { cudaStatus = cudaMemcpy(d_in_out, h_in_backup, in_size * sizeof(T), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); } cudaDeviceSynchronize(); timer.stop("Copy To Device"); timer.print("Copy To Device", 1); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset memcpy(h_in_out, h_in_backup, in_size * sizeof(T)); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); cudaDeviceSynchronize(); // Launch GPU threads if(p.n_gpu_blocks > 0) { // Kernel launch assert(p.n_gpu_threads <= max_gpu_threads && "The runtime block size is greater than the maximum runtime block size that can be used on this device"); cudaStatus = cudaMemcpy(d_in_out, h_in_backup, in_size * sizeof(T), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); // start timer if(rep >= p.n_warmup) timer.start("Step 1"); // Step 1 cudaStatus = call_PTTWAC_soa_asta(M_ * m * N_, p.n_gpu_threads, M_ * m, N_, n, d_in_out, (int*)d_finished, (int*)d_head, sizeof(int) + sizeof(int)); CUDA_ERR(); // end timer if(rep >= p.n_warmup) timer.stop("Step 1"); // start timer if(rep >= p.n_warmup) timer.start("Step 2"); // Step 2 cudaStatus = call_BS_marshal(M_ * N_, p.n_gpu_threads, m, n, d_in_out, m * n * sizeof(T)); CUDA_ERR(); // end timer if(rep >= p.n_warmup) timer.stop("Step 2"); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); // start timer if(rep >= p.n_warmup) timer.start("Step 3"); // Step 3 for(int i = 0; i < N_; i++){ cudaStatus = call_PTTWAC_soa_asta(M_ * n, p.n_gpu_threads, M_, n, m, d_in_out + i * M_ * n * m, (int*)d_finished + i * M_ * n, (int*)d_head + i, sizeof(int) + sizeof(int)); CUDA_ERR(); } // end timer if(rep >= p.n_warmup) timer.stop("Step 3"); } cudaDeviceSynchronize(); } timer.print("Step 1", p.n_reps); timer.print("Step 2", p.n_reps); timer.print("Step 3", p.n_reps); // Copy back timer.start("Copy Back and Merge"); if(p.n_gpu_blocks != 0) { cudaStatus = cudaMemcpy(h_in_out, d_in_out, in_size * sizeof(T), cudaMemcpyDeviceToHost); CUDA_ERR(); cudaDeviceSynchronize(); } timer.stop("Copy Back and Merge"); timer.print("Copy Back and Merge", 1); // Verify answer verify(h_in_out, h_in_backup, M_ * m, N_ * n, 1); // Free memory timer.start("Deallocation"); free(h_in_out); free(h_finished); free(h_head); if(p.n_gpu_blocks != 0) { cudaStatus = cudaFree(d_in_out); cudaStatus = cudaFree(d_finished); cudaStatus = cudaFree(d_head); CUDA_ERR(); } free(h_in_backup); cudaDeviceSynchronize(); timer.stop("Deallocation"); timer.print("Deallocation", 1); // Release timers timer.release("Allocation"); timer.release("Initialization"); timer.release("Copy To Device"); timer.release("Step 1"); timer.release("Step 2"); timer.release("Step 3"); timer.release("Copy Back and Merge"); timer.release("Deallocation"); printf("Test Passed\n"); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #ifndef DOUBLE_PRECISION #define DOUBLE_PRECISION 1 #endif #if DOUBLE_PRECISION #define T long int // double #else #define T int // float #endif #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/support/cuda-setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) #define CUDA_ERR() \ if(cudaStatus != cudaSuccess) { \ fprintf(stderr, "CUDA error: %s\n at %s, %d\n", cudaGetErrorString(cudaStatus), __FILE__, __LINE__); \ exit(-1); \ } struct CUDASetup { cudaDeviceProp device_prop; CUDASetup(int device) { cudaError_t cudaStatus; cudaStatus = cudaSetDevice(device); CUDA_ERR(); cudaStatus = cudaGetDeviceProperties(&device_prop, device); CUDA_ERR(); fprintf(stderr, "%s\t", device_prop.name); } int max_gpu_threads() { return device_prop.maxThreadsPerBlock; } }; ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { cudaEventCreate(&startTime[name]); cudaEventCreate(&stopTime[name]); time[name] = 0.0; } cudaEventRecord(startTime[name], 0); } void stop(string name) { cudaEventRecord(stopTime[name],0); cudaEventSynchronize(stopTime[name]); float part_time = 0.0; cudaEventElapsedTime(&part_time, startTime[name], stopTime[name]); time[name] += part_time; } void print(string name, unsigned int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / REP); } void release(string name){ cudaEventDestroy(startTime[name]); cudaEventDestroy(stopTime[name]); } }; ================================================ FILE: golang/uPIMulator/benchmark/TRNS/baselines/gpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include inline int compare_output(T *output, T *ref, int dim) { int i; for(i = 0; i < dim; i++) { T diff = fabs(ref[i] - output[i]); if((diff - 0.0f) > 0.00001f && diff > 0.01 * fabs(ref[i])) { printf("line: %d ref: %f actual: %f diff: %f\n", i, ref[i], output[i], diff); exit(EXIT_FAILURE); } } return 0; } // Sequential transposition for comparison purposes //[w][h/t][t] to [h/t][w][t] static void trns_host(T* input, unsigned int A, unsigned int B, unsigned int b){ T* output = (T*) malloc(sizeof(T) * A * B * b); unsigned int next; for (unsigned int j = 0; j < b; j++){ for (unsigned int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (unsigned int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } inline void verify(T *input2, T *input, int height, int width, int tile_size) { trns_host(input, height, width, tile_size); compare_output(input2, input, height * width); } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/dpu/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/TRNS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(TRNS_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/TRNS/dpu/task.c ================================================ /* * 3-step matrix transposition with multiple tasklets * Acks: Stefano Ballarin (P&S PIM Fall 2020) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; uint32_t curr_tile = 0; // protected by MUTEX uint32_t get_tile(); void read_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n); void write_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n); void read_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m); void write_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m); _Bool get_done(uint32_t done_array_step3, uint32_t address, T* read_done); _Bool get_and_set_done(uint32_t done_array_step3, uint32_t address, T* read_done); // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Mutexes MUTEX_INIT(tile_mutex); MUTEX_INIT(done_mutex); extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Step 2: 0010 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t A = (uint32_t)DPU_MRAM_HEAP_POINTER; // A in MRAM uint32_t M_ = DPU_INPUT_ARGUMENTS.M_; uint32_t m = DPU_INPUT_ARGUMENTS.m; uint32_t n = DPU_INPUT_ARGUMENTS.n; T* data = (T*) mem_alloc(m * n * sizeof(T)); T* backup = (T*) mem_alloc(m * n * sizeof(T)); for(unsigned int tile = tasklet_id; tile < M_; tile += NR_TASKLETS){ read_tile_step2(A, tile * m * n, data, m, n); for (unsigned int i = 0; i < m * n; i++){ backup[(i * m) - (m * n - 1) * (i / n)] = data[i]; } write_tile_step2(A, tile * m * n, backup, m, n); } return 0; } // Step 3: 0100 int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t m = DPU_INPUT_ARGUMENTS.m; uint32_t n = DPU_INPUT_ARGUMENTS.n; uint32_t M_ = DPU_INPUT_ARGUMENTS.M_; uint32_t done_array = (uint32_t)(DPU_MRAM_HEAP_POINTER + M_ * m * n * sizeof(T)); const uint32_t tile_max = M_ * n - 1; // Tile id upper bound T* data = (T*)mem_alloc(sizeof(T) * m); T* backup = (T*)mem_alloc(sizeof(T) * m); T* read_done = (T*)mem_alloc(sizeof(T)); uint32_t tile; _Bool done; tile = get_tile(); while (tile < tile_max){ uint32_t next_in_cycle = ((tile * M_) - tile_max * (tile / n)); if (next_in_cycle == tile){ tile = get_tile(); continue; } read_tile_step3(A, tile * m, data, m); done = get_done(done_array, tile, read_done); for(; done == 0; next_in_cycle = ((next_in_cycle * M_) - tile_max * (next_in_cycle / n))){ read_tile_step3(A, next_in_cycle * m, backup, m); done = get_and_set_done(done_array, next_in_cycle, read_done); if(!done) { write_tile_step3(A, next_in_cycle * m, data, m); } for(uint32_t i = 0; i < m; i++){ data[i] = backup[i]; } } tile = get_tile(); } return 0; } // Auxiliary functions uint32_t __attribute__ ((noinline)) get_tile(){ mutex_lock(tile_mutex); uint32_t value = curr_tile; curr_tile++; mutex_unlock(tile_mutex); return value; } void __attribute__ ((noinline)) read_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n){ int rest = m * n; int transfer; while(rest > 0){ if(rest * sizeof(T) > 2048){ transfer = 2048 / sizeof(T); } else { transfer = rest; } mram_read((__mram_ptr void*)(A + (offset + m * n - rest) * sizeof(T)), variable + (m * n - rest) * sizeof(T), sizeof(T) * transfer); rest -= transfer; } } void __attribute__ ((noinline)) write_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n){ int rest = m * n; int transfer; while(rest > 0){ if(rest * sizeof(T) > 2048){ transfer = 2048 / sizeof(T); } else { transfer = rest; } mram_write(variable + (m * n - rest) * sizeof(T), (__mram_ptr void*)(A + (offset + m * n - rest) * sizeof(T)), sizeof(T) * transfer); rest -= transfer; } } void __attribute__ ((noinline)) read_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m){ mram_read((__mram_ptr void*)(A + offset * sizeof(T)), variable, sizeof(T) * m); } void __attribute__ ((noinline)) write_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m){ mram_write(variable, (__mram_ptr void*)(A + offset * sizeof(T)), sizeof(T) * m); } _Bool __attribute__ ((noinline)) get_done(uint32_t done_array_step3, uint32_t address, T* read_done){ uint32_t result; mutex_lock(done_mutex); mram_read((__mram_ptr void*)(done_array_step3 + address), read_done, sizeof(T)); result = ((*read_done & (0x01 << (address % sizeof(T)))) != 0); mutex_unlock(done_mutex); return (_Bool)result; } _Bool __attribute__ ((noinline))get_and_set_done(uint32_t done_array_step3, uint32_t address, T* read_done){ uint32_t result; mutex_lock(done_mutex); mram_read((__mram_ptr void*)(done_array_step3 + address), read_done, sizeof(T)); result = ((*read_done & (0x01 << (address % sizeof(T)))) != 0); *read_done |= (0x01 << (address % sizeof(T))); mram_write(read_done, (__mram_ptr void*)(done_array_step3 + address), sizeof(T)); mutex_unlock(done_mutex); return (_Bool)result; } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/host/app.c ================================================ /** * app.c * TRNS Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A_host; static T* A_backup; static T* A_result; // Create input arrays static void read_input(T* A, unsigned int nr_elements) { srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { A[i] = (T) (rand()); } } // Compute output in the host static void trns_host(T* input, unsigned int A, unsigned int B, unsigned int b){ T* output = (T*) malloc(sizeof(T) * A * B * b); unsigned int next; for (unsigned int j = 0; j < b; j++){ for (unsigned int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (unsigned int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif unsigned int i = 0; unsigned int N_ = p.N_; const unsigned int n = p.n; const unsigned int M_ = p.M_; const unsigned int m = p.m; N_ = p.exp == 0 ? N_ * NR_DPUS : N_; // Input/output allocation A_host = malloc(M_ * m * N_ * n * sizeof(T)); A_backup = malloc(M_ * m * N_ * n * sizeof(T)); A_result = malloc(M_ * m * N_ * n * sizeof(T)); T* done_host = malloc(M_ * n); // Host array to reset done array of step 3 memset(done_host, 0, M_ * n); // Create an input file with arbitrary data read_input(A_host, M_ * m * N_ * n); memcpy(A_backup, A_host, M_ * m * N_ * n * sizeof(T)); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\n", NR_TASKLETS); printf("M_\t%u, m\t%u, N_\t%u, n\t%u\n", M_, m, N_, n); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { int timer_fix = 0; // Compute output on CPU (performance comparison and verification purposes) memcpy(A_host, A_backup, M_ * m * N_ * n * sizeof(T)); if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup + timer_fix); trns_host(A_host, M_ * m, N_ * n, 1); if(rep >= p.n_warmup) stop(&timer, 0); unsigned int curr_dpu = 0; unsigned int active_dpus; unsigned int active_dpus_before = 0; unsigned int first_round = 1; while(curr_dpu < N_){ // Allocate DPUs and load binary if((N_ - curr_dpu) > NR_DPUS){ active_dpus = NR_DPUS; } else { active_dpus = (N_ - curr_dpu); } if((active_dpus_before != active_dpus) && (!(first_round))){ DPU_ASSERT(dpu_free(dpu_set)); DPU_ASSERT(dpu_alloc(active_dpus, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); } else if (first_round){ DPU_ASSERT(dpu_alloc(active_dpus, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); } printf("Load input data (step 1)\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup + timer_fix); // Load input matrix (step 1) for(unsigned int j = 0; j < M_ * m; j++){ unsigned int i = 0; DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpu_prepare_xfer(dpu, &A_backup[j * N_ * n + n * (i + curr_dpu)])); i++; } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, sizeof(T) * j * n, sizeof(T) * n, DPU_XFER_DEFAULT)); } if(rep >= p.n_warmup) stop(&timer, 1); // Reset done array (for step 3) DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpu_prepare_xfer(dpu, done_host)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, M_ * m * n * sizeof(T), (M_ * n) / 8 == 0 ? 8 : M_ * n, DPU_XFER_DEFAULT)); unsigned int kernel = 0; dpu_arguments_t input_arguments = {m, n, M_, kernel}; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); printf("Run step 2 on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup){ start(&timer, 2, rep - p.n_warmup + timer_fix); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup){ stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif kernel = 1; dpu_arguments_t input_arguments2 = {m, n, M_, kernel}; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments2)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments2), DPU_XFER_DEFAULT)); printf("Run step 3 on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup){ start(&timer, 3, rep - p.n_warmup + timer_fix); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup){ stop(&timer, 3); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); if(rep >= p.n_warmup) start(&timer, 4, rep - p.n_warmup + timer_fix); DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpu_prepare_xfer(dpu, (T*)(&A_result[curr_dpu * m * n * M_]))); curr_dpu++; } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, sizeof(T) * m * n * M_, DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 4); if(first_round){ first_round = 0; } timer_fix++; } DPU_ASSERT(dpu_free(dpu_set)); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU (Step 1) "); print(&timer, 1, p.n_reps); printf("Step 2 "); print(&timer, 2, p.n_reps); printf("Step 3 "); print(&timer, 3, p.n_reps); printf("DPU-CPU "); print(&timer, 4, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; for (i = 0; i < M_ * m * N_ * n; i++) { if(A_host[i] != A_result[i]){ status = false; #if PRINT printf("%d: %lu -- %lu\n", i, A_host[i], A_result[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A_host); free(A_backup); free(A_result); free(done_host); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/TRNS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T int64_t // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t m; uint32_t n; uint32_t M_; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/TRNS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int M_; unsigned int m; unsigned int N_; unsigned int n; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=12288 elements)" "\n -p N_ (default=1 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.M_ = 12288; p.m = 16; p.N_ = 1; p.n = 8; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hw:e:x:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 'm': p.m = atoi(optarg); break; case 'n': p.n = atoi(optarg); break; case 'o': p.M_ = atoi(optarg); break; case 'p': p.N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/TRNS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/TS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/TS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) COMMON_INCLUDES := support HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -lm DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -n 131072 ================================================ FILE: golang/uPIMulator/benchmark/TS/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/TS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(TS_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/TS/dpu/task.c ================================================ /* * STREAMP implementation of Matrix Profile with multiple tasklets * */ #include #include #include #include #include #include #include #include "common.h" #define DOTPIP BLOCK_SIZE / sizeof(DTYPE) __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_result_t DPU_RESULTS[NR_TASKLETS]; // Dot product void __attribute__ ((noinline)) dot_product(DTYPE *vectorA, DTYPE *vectorA_aux, DTYPE *vectorB, DTYPE * result) { for(uint32_t i = 0; i < BLOCK_SIZE / sizeof(DTYPE); i++) { for(uint32_t j = 0; j < DOTPIP; j++) { if((j + i) > BLOCK_SIZE / sizeof(DTYPE) - 1) { result[j] += vectorA_aux[(j + i) - BLOCK_SIZE / sizeof(DTYPE)] * vectorB[i]; } else { result[j] += vectorA[j + i] * vectorB[i]; } } } } BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int(*kernels[nr_kernels])(void) = {main_kernel1}; int main(void){ // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if(tasklet_id == 0){ mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); // Input arguments uint32_t query_length = DPU_INPUT_ARGUMENTS.query_length; DTYPE query_mean = DPU_INPUT_ARGUMENTS.query_mean; DTYPE query_std = DPU_INPUT_ARGUMENTS.query_std; uint32_t slice_per_dpu = DPU_INPUT_ARGUMENTS.slice_per_dpu; // Boundaries for current tasklet uint32_t myStartElem = tasklet_id * (slice_per_dpu / (NR_TASKLETS)); uint32_t myEndElem = myStartElem + (slice_per_dpu / (NR_TASKLETS)) - 1; // Check time series limit if(myEndElem > slice_per_dpu - query_length) myEndElem = slice_per_dpu - query_length; // Starting address of the current processing block in MRAM uint32_t mem_offset = (uint32_t) DPU_MRAM_HEAP_POINTER; // Starting address of the query subsequence uint32_t current_mram_block_addr_query = (uint32_t)(mem_offset); mem_offset += query_length * sizeof(DTYPE); // Starting address of the time series slice mem_offset += myStartElem * sizeof(DTYPE); uint32_t starting_offset_ts = mem_offset; uint32_t current_mram_block_addr_TS = (uint32_t) mem_offset; // Starting address of the time series means mem_offset += (slice_per_dpu + query_length) * sizeof(DTYPE); uint32_t current_mram_block_addr_TSMean = (uint32_t)(mem_offset); // Starting address of the time series standard deviations mem_offset += (slice_per_dpu + query_length) * sizeof(DTYPE); uint32_t current_mram_block_addr_TSSigma = (uint32_t)(mem_offset); // Initialize local caches to store the MRAM blocks DTYPE *cache_TS = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TS_aux = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_query = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TSMean = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TSSigma = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_dotprods = (DTYPE *) mem_alloc(BLOCK_SIZE); // Create result structure pointer dpu_result_t *result = &DPU_RESULTS[tasklet_id]; // Auxiliary variables DTYPE distance; DTYPE min_distance = DTYPE_MAX; uint32_t min_index = 0; for(uint32_t i = myStartElem; i < myEndElem; i+= (BLOCK_SIZE / sizeof(DTYPE))) { for(uint32_t d = 0; d < DOTPIP; d++) cache_dotprods[d] = 0; current_mram_block_addr_TS = (uint32_t) starting_offset_ts + (i - myStartElem) * sizeof(DTYPE); current_mram_block_addr_query = (uint32_t) DPU_MRAM_HEAP_POINTER; for(uint32_t j = 0; j < (query_length) / (BLOCK_SIZE / sizeof(DTYPE)); j++) { mram_read((__mram_ptr void const *) current_mram_block_addr_TS, cache_TS, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_TS + BLOCK_SIZE, cache_TS_aux, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_query, cache_query, BLOCK_SIZE); current_mram_block_addr_TS += BLOCK_SIZE; current_mram_block_addr_query += BLOCK_SIZE; dot_product(cache_TS, cache_TS_aux, cache_query, cache_dotprods); } mram_read((__mram_ptr void const *) current_mram_block_addr_TSMean, cache_TSMean, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_TSSigma, cache_TSSigma, BLOCK_SIZE); current_mram_block_addr_TSMean += BLOCK_SIZE; current_mram_block_addr_TSSigma += BLOCK_SIZE; for (uint32_t k = 0; k < (BLOCK_SIZE / sizeof(DTYPE)); k++) { distance = 2 * ((DTYPE) query_length - (cache_dotprods[k] - (DTYPE) query_length * cache_TSMean[k] * query_mean) / (cache_TSSigma[k] * query_std)); if(distance < min_distance) { min_distance = distance; min_index = i + k; } } } // Save the result result->minValue = min_distance; result->minIndex = min_index; return 0; } ================================================ FILE: golang/uPIMulator/benchmark/TS/host/app.c ================================================ /** * app.c * TS Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include #include #if ENERGY #include #endif #include "params.h" #include "timer.h" // Define the DPU Binary path as DPU_BINARY here #define DPU_BINARY "./bin/ts_dpu" #define MAX_DATA_VAL 127 static DTYPE tSeries[1 << 26]; static DTYPE query [1 << 15]; static DTYPE AMean [1 << 26]; static DTYPE ASigma [1 << 26]; static DTYPE minHost; static DTYPE minHostIdx; // Create input arrays static DTYPE *create_test_file(unsigned int ts_elements, unsigned int query_elements) { srand(0); for (uint64_t i = 0; i < ts_elements; i++) { tSeries[i] = i % MAX_DATA_VAL; } for (uint64_t i = 0; i < query_elements; i++) { query[i] = i % MAX_DATA_VAL; } return tSeries; } // Compute output in the host static void streamp(DTYPE* tSeries, DTYPE* AMean, DTYPE* ASigma, int ProfileLength, DTYPE* query, int queryLength, DTYPE queryMean, DTYPE queryStdDeviation) { DTYPE distance; DTYPE dotprod; minHost = INT32_MAX; minHostIdx = 0; for (int subseq = 0; subseq < ProfileLength; subseq++) { dotprod = 0; for(int j = 0; j < queryLength; j++) { dotprod += tSeries[j + subseq] * query[j]; } distance = 2 * (queryLength - (dotprod - queryLength * AMean[subseq] * queryMean) / (ASigma[subseq] * queryStdDeviation)); if(distance < minHost) { minHost = distance; minHostIdx = subseq; } } } static void compute_ts_statistics(unsigned int timeSeriesLength, unsigned int ProfileLength, unsigned int queryLength) { double* ACumSum = malloc(sizeof(double) * timeSeriesLength); ACumSum[0] = tSeries[0]; for (uint64_t i = 1; i < timeSeriesLength; i++) ACumSum[i] = tSeries[i] + ACumSum[i - 1]; double* ASqCumSum = malloc(sizeof(double) * timeSeriesLength); ASqCumSum[0] = tSeries[0] * tSeries[0]; for (uint64_t i = 1; i < timeSeriesLength; i++) ASqCumSum[i] = tSeries[i] * tSeries[i] + ASqCumSum[i - 1]; double* ASum = malloc(sizeof(double) * ProfileLength); ASum[0] = ACumSum[queryLength - 1]; for (uint64_t i = 0; i < timeSeriesLength - queryLength; i++) ASum[i + 1] = ACumSum[queryLength + i] - ACumSum[i]; double* ASumSq = malloc(sizeof(double) * ProfileLength); ASumSq[0] = ASqCumSum[queryLength - 1]; for (uint64_t i = 0; i < timeSeriesLength - queryLength; i++) ASumSq[i + 1] = ASqCumSum[queryLength + i] - ASqCumSum[i]; double * AMean_tmp = malloc(sizeof(double) * ProfileLength); for (uint64_t i = 0; i < ProfileLength; i++) AMean_tmp[i] = ASum[i] / queryLength; double* ASigmaSq = malloc(sizeof(double) * ProfileLength); for (uint64_t i = 0; i < ProfileLength; i++) ASigmaSq[i] = ASumSq[i] / queryLength - AMean[i] * AMean[i]; for (uint64_t i = 0; i < ProfileLength; i++) { ASigma[i] = sqrt(ASigmaSq[i]); AMean[i] = (DTYPE) AMean_tmp[i]; } free(ACumSum); free(ASqCumSum); free(ASum); free(ASumSq); free(ASigmaSq); free(AMean_tmp); } // Main of the Host Application int main(int argc, char **argv) { // Timer declaration Timer timer; struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif unsigned long int ts_size = p.input_size_n; const unsigned int query_length = p.input_size_m; // Size adjustment if(ts_size % (nr_of_dpus * NR_TASKLETS*query_length)) ts_size = ts_size + (nr_of_dpus * NR_TASKLETS * query_length - ts_size % (nr_of_dpus * NR_TASKLETS*query_length)); // Create an input file with arbitrary data create_test_file(ts_size, query_length); compute_ts_statistics(ts_size, ts_size - query_length, query_length); DTYPE query_mean; double queryMean = 0; for(unsigned i = 0; i < query_length; i++) queryMean += query[i]; queryMean /= (double) query_length; query_mean = (DTYPE) queryMean; DTYPE query_std; double queryStdDeviation; double queryVariance = 0; for(unsigned i = 0; i < query_length; i++) { queryVariance += (query[i] - queryMean) * (query[i] - queryMean); } queryVariance /= (double) query_length; queryStdDeviation = sqrt(queryVariance); query_std = (DTYPE) queryStdDeviation; DTYPE *bufferTS = tSeries; DTYPE *bufferQ = query; DTYPE *bufferAMean = AMean; DTYPE *bufferASigma = ASigma; uint32_t slice_per_dpu = ts_size / nr_of_dpus; unsigned int kernel = 0; dpu_arguments_t input_arguments = {ts_size, query_length, query_mean, query_std, slice_per_dpu, 0, kernel}; uint32_t mem_offset; dpu_result_t result; result.minValue = INT32_MAX; result.minIndex = 0; result.maxValue = 0; result.maxIndex = 0; for (int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { if (rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); uint32_t i = 0; DPU_FOREACH(dpu_set, dpu) { input_arguments.exclusion_zone = 0; DPU_ASSERT(dpu_copy_to(dpu, "DPU_INPUT_ARGUMENTS", 0, (const void *) &input_arguments, sizeof(input_arguments))); i++; } i = 0; mem_offset = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferQ)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, query_length * sizeof(DTYPE), DPU_XFER_DEFAULT)); i = 0; mem_offset += query_length * sizeof(DTYPE); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferTS + slice_per_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset,(slice_per_dpu + query_length)*sizeof(DTYPE), DPU_XFER_DEFAULT)); mem_offset += ((slice_per_dpu + query_length) * sizeof(DTYPE)); i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferAMean + slice_per_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset, (slice_per_dpu + query_length)*sizeof(DTYPE), DPU_XFER_DEFAULT)); i = 0; mem_offset += ((slice_per_dpu + query_length) * sizeof(DTYPE)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferASigma + slice_per_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset, (slice_per_dpu + query_length)*sizeof(DTYPE), DPU_XFER_DEFAULT)); if (rep >= p.n_warmup) stop(&timer, 1); // Run kernel on DPUs if (rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if (rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } dpu_result_t* results_retrieve[nr_of_dpus]; if (rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_result_t*)malloc(NR_TASKLETS * sizeof(dpu_result_t)); } DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_result_t), DPU_XFER_DEFAULT)); i = 0; DPU_FOREACH(dpu_set, dpu, i) { for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { if(results_retrieve[i][each_tasklet].minValue < result.minValue && results_retrieve[i][each_tasklet].minValue > 0) { result.minValue = results_retrieve[i][each_tasklet].minValue; result.minIndex = (DTYPE)results_retrieve[i][each_tasklet].minIndex + (i * slice_per_dpu); } } free(results_retrieve[i]); i++; } if(rep >= p.n_warmup) stop(&timer, 3); #if PRINT printf("LOGS\n"); DPU_FOREACH(dpu_set, dpu) { DPU_ASSERT(dpu_log_read(dpu, stdout)); } #endif if (rep >= p.n_warmup) start(&timer, 4, rep - p.n_warmup); streamp(tSeries, AMean, ASigma, ts_size - query_length - 1, query, query_length, query_mean, query_std); if(rep >= p.n_warmup) stop(&timer, 4); } #if ENERGY double acc_energy, avg_energy, acc_time, avg_time; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_ACCUMULATE, &acc_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &avg_energy)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_ACCUMULATE, &acc_time)); DPU_ASSERT(dpu_probe_get(&probe, DPU_TIME, DPU_AVERAGE, &avg_time)); #endif // Print timing results printf("CPU Version Time (ms): "); print(&timer, 4, p.n_reps); printf("Inter-DPU Time (ms): "); print(&timer, 0, p.n_reps); printf("CPU-DPU Time (ms): "); print(&timer, 1, p.n_reps); printf("DPU Kernel Time (ms): "); print(&timer, 2, p.n_reps); printf("DPU-CPU Time (ms): "); print(&timer, 3, p.n_reps); #if ENERGY printf("Energy (J): %f J\t", avg_energy); #endif int status = (minHost == result.minValue); if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] results are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] results differ!\n"); } DPU_ASSERT(dpu_free(dpu_set)); #if ENERGY DPU_ASSERT(dpu_probe_deinit(&probe)); #endif return 0; } ================================================ FILE: golang/uPIMulator/benchmark/TS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #endif // Data type #define DTYPE int32_t #define DTYPE_MAX INT32_MAX typedef struct { uint32_t ts_length; uint32_t query_length; DTYPE query_mean; DTYPE query_std; uint32_t slice_per_dpu; int32_t exclusion_zone; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; }dpu_arguments_t; typedef struct { DTYPE minValue; uint32_t minIndex; DTYPE maxValue; uint32_t maxIndex; }dpu_result_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang/uPIMulator/benchmark/TS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" // Params --------------------------------------------------------------------- typedef struct Params { unsigned long input_size_n; unsigned long input_size_m; int n_warmup; int n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -n n (TS length. Default=64K elements)" "\n -m m (Query length. Default=256 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size_n = 1 << 16; p.input_size_m = 1 << 8; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hw:e:n:m:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'n': p.input_size_n = atol(optarg); break; case 'm': p.input_size_m = atol(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/TS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[5]; struct timeval stopTime[5]; double time[5]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/UNI/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/UNI/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/cpu/Makefile ================================================ all: gcc -o uni -fopenmp app_baseline.c clean: rm uni ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/cpu/README ================================================ Unique (UNI) Compilation instructions make Execution instructions ./uni -i 1258291200 -t 4 Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/cpu/app_baseline.c ================================================ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" #define T int64_t static int pos; static T *A; static T *B; static T *C; static T *C2; // Create a "test file" static T *create_test_file(unsigned int nr_elements) { //srand(0); A = (T*) malloc(nr_elements * sizeof(T)); B = (T*) malloc(nr_elements * sizeof(T)); C = (T*) malloc(nr_elements * sizeof(T)); printf("nr_elements\t%u\t", nr_elements); for (int i = 0; i < nr_elements; i++) { //A[i] = (unsigned int) (rand()); //A[i] = i+1; //A[i] = i%2==0?i+1:i; A[i] = i%2==0?i:i+1; B[i] = 0; } return A; } // Compute output in the host static int unique_host(int size, int t) { pos = 0; C[pos] = A[pos]; omp_set_num_threads(t); #pragma omp parallel for for(int my = 1; my < size; my++) { if(A[my] != A[my-1]) { int p; #pragma omp atomic update pos++; p = pos; C[p] = A[my]; } } return pos; } // Params typedef struct Params { int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16 << 20; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hd:i:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } // Main int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; uint32_t accum = 0; int total_count; // Create an input file with arbitrary data create_test_file(file_size); Timer timer; start(&timer, 0, 0); total_count = unique_host(file_size, p.n_threads); stop(&timer, 0); printf("Total count = %d\t", total_count); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc unique.cu -I/usr/local/cuda/include -lm -o unique -D COARSENING=32 -D THREADS=512 -D INT64 clean: rm unique ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/gpu/README ================================================ Unique (UNI) Compilation instructions make Execution instructions ./unique 0 50 1258291200 Compilation flags FLOAT - For single precision arrays (Default: Double precision) INT - For integer arrays THREADS - Thread block size (Default: 1024) COARSENING - Coarsening factor (Default: 16 (SP and INT); 8 (DP)) ATOMIC - Global atomics for synchronization (Default: No atomics) Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/gpu/ds.h ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include #include #include #include #include #include #include #include #ifdef FLOAT #define T float #elif INT #define T int #elif INT64 #define T int64_t #else #define T double #endif #ifdef THREADS #define L_DIM THREADS #else #define L_DIM 1024 #endif #ifdef COARSENING #define REGS COARSENING #else #ifdef FLOAT #define REGS 16 #elif INT #define REGS 16 #else #define REGS 8 #endif #endif #ifdef ATOMIC #define ATOM 1 #else #define ATOM 0 #endif #define WARP_SIZE 32 #define PRINT 0 // Dynamic allocation of runtime workgroup id __device__ int dynamic_wg_id(volatile unsigned int *flags, const int num_flags){ __shared__ int gid_; if (threadIdx.x == 0) gid_ = atomicAdd((unsigned int*)&flags[num_flags + 1], 1); __syncthreads(); int my_s = gid_; return my_s; } // Set global synchronization (regular DS) __device__ void ds_sync(volatile unsigned int *flags, const int my_s){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} atomicOr((unsigned int*)&flags[my_s + 1], 1); } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} flags[my_s + 1] = 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS) __device__ void ds_sync_irregular(volatile unsigned int *flags, const int my_s, int *count){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} int flag = flags[my_s]; atomicAdd((unsigned int*)&flags[my_s + 1], flag + *count); *count = flag - 1; } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} int flag = flags[my_s]; flags[my_s + 1] = flag + *count; *count = flag - 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS Partition) __device__ void ds_sync_irregular_partition(volatile unsigned int *flags1, volatile unsigned int *flags2, const int my_s, int *count1, int *count2){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags1[my_s], 0) == 0){} int flag2 = flags2[my_s]; atomicAdd((unsigned int*)&flags2[my_s + 1], flag2 + *count); int flag1 = flags1[my_s]; atomicAdd((unsigned int*)&flags1[my_s + 1], flag1 + *count); *count1 = flag1 - 1; *count2 = flag2 - 1; } #else if (threadIdx.x == 0){ while (flags1[my_s] == 0){} int flag2 = flags2[my_s]; flags2[my_s + 1] = flag2 + *count2; int flag1 = flags1[my_s]; flags1[my_s + 1] = flag1 + *count1; *count1 = flag1 - 1; *count2 = flag2 - 1; } #endif __syncthreads(); } // Reduction kernel (CUDA SDK reduce6) template __device__ void reduction(S *count, S local_cnt){ __shared__ S sdata[L_DIM]; unsigned int tid = threadIdx.x; S mySum = local_cnt; // each runtime puts its local sum into shared memory sdata[tid] = local_cnt; __syncthreads(); // do reduction in shared mem if ((blockDim.x >= 1024) && (tid < 512)){ sdata[tid] = mySum = mySum + sdata[tid + 512]; } __syncthreads(); if ((blockDim.x >= 512) && (tid < 256)){ sdata[tid] = mySum = mySum + sdata[tid + 256]; } __syncthreads(); if ((blockDim.x >= 256) && (tid < 128)){ sdata[tid] = mySum = mySum + sdata[tid + 128]; } __syncthreads(); if ((blockDim.x >= 128) && (tid < 64)){ sdata[tid] = mySum = mySum + sdata[tid + 64]; } __syncthreads(); #if (__CUDA_ARCH__ >= 300 ) if ( tid < 32 ){ // Fetch final intermediate sum from 2nd warp if (blockDim.x >= 64) mySum += sdata[tid + 32]; // Reduce final warp using shuffle #pragma unroll for (int offset = WARP_SIZE/2; offset > 0; offset /= 2){ //mySum += __shfl_down(mySum, offset); mySum += __shfl_xor(mySum, offset); } } #else // fully unroll reduction within a single warp if ((blockDim.x >= 64) && (tid < 32)){ sdata[tid] = mySum = mySum + sdata[tid + 32]; } __syncthreads(); if ((blockDim.x >= 32) && (tid < 16)){ sdata[tid] = mySum = mySum + sdata[tid + 16]; } __syncthreads(); if ((blockDim.x >= 16) && (tid < 8)){ sdata[tid] = mySum = mySum + sdata[tid + 8]; } __syncthreads(); if ((blockDim.x >= 8) && (tid < 4)){ sdata[tid] = mySum = mySum + sdata[tid + 4]; } __syncthreads(); if ((blockDim.x >= 4) && (tid < 2)){ sdata[tid] = mySum = mySum + sdata[tid + 2]; } __syncthreads(); if ((blockDim.x >= 2) && ( tid < 1)){ sdata[tid] = mySum = mySum + sdata[tid + 1]; } __syncthreads(); #endif // write result for this block to global mem if (tid == 0) *count = mySum; } // Binary prefix-sum (GPU Computing Gems) __device__ inline int lane_id(void) { return threadIdx.x % WARP_SIZE; } __device__ inline int warp_id(void) { return threadIdx.x / WARP_SIZE; } __device__ unsigned int warp_prefix_sums(bool p){ unsigned int b = __ballot(p); return __popc(b & ((1 << lane_id()) - 1)); } __device__ int warp_scan(int val, volatile int *s_data){ #if (__CUDA_ARCH__ < 300 ) int idx = 2 * threadIdx.x - (threadIdx.x & (WARP_SIZE - 1)); s_data[idx] = 0; idx += WARP_SIZE; int t = s_data[idx] = val; s_data[idx] = t = t + s_data[idx - 1]; s_data[idx] = t = t + s_data[idx - 2]; s_data[idx] = t = t + s_data[idx - 4]; s_data[idx] = t = t + s_data[idx - 8]; s_data[idx] = t = t + s_data[idx - 16]; return s_data[idx - 1]; #else int x = val; #pragma unroll for(int offset = 1; offset < 32; offset <<= 1){ // From GTC: Kepler shuffle tips and tricks: #if 0 int y = __shfl_up(x, offset); if(lane_id() >= offset) x += y; #else asm volatile("{" " .reg .s32 r0;" " .reg .pred p;" " shfl.up.b32 r0|p, %0, %1, 0x0;" " @p add.s32 r0, r0, %0;" " mov.s32 %0, r0;" "}" : "+r"(x) : "r"(offset)); #endif } return x - val; #endif } __device__ int block_binary_prefix_sums(int* count, int x){ __shared__ int sdata[L_DIM]; // A. Exclusive scan within each warp int warpPrefix = warp_prefix_sums(x); // B. Store in shared memory if(lane_id() == WARP_SIZE - 1) sdata[warp_id()] = warpPrefix + x; __syncthreads(); // C. One warp scans in shared memory if(threadIdx.x < WARP_SIZE) sdata[threadIdx.x] = warp_scan(sdata[threadIdx.x], sdata); __syncthreads(); // D. Each runtime calculates it final value int thread_out_element = warpPrefix + sdata[warp_id()]; int output = thread_out_element + *count; __syncthreads(); if(threadIdx.x == blockDim.x - 1) *count += (thread_out_element + x); return output; } ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/gpu/kernel.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ __device__ T warp_up(T reg, int delta){ __shared__ volatile T R[L_DIM]; R[threadIdx.x] = reg; return (lane_id() - delta >= 0 ? R[threadIdx.x - delta] : 0); } __device__ T __shuffle_up(T* matrix, int my_s, int pos, T regi, int i){ #if (__CUDA_ARCH__ >= 300 ) T p = __shfl_up(regi, 1); #else T p = warp_up(regi, 1); #endif if(lane_id() == 0 && i > 0) p = matrix[pos - 1]; if(lane_id() == 0 && threadIdx.x != 0 && i == 0) p = matrix[pos - 1]; if(my_s > 0 && threadIdx.x == 0 && i == 0) p = matrix[pos - 1]; if(my_s == 0 && threadIdx.x == 0 && i == 0) p = -1; return p; } __global__ void unique(T *matrix_out, T *matrix, int size, volatile unsigned int *flags) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(reg[j] != __shuffle_up(matrix, my_s, pos, reg[j], j)) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } ================================================ FILE: golang/uPIMulator/benchmark/UNI/baselines/gpu/unique.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include "ds.h" #include "kernel.cu" // Sequential CPU version void cpu_unique(T* output, T* input, int elements){ int j = 0; output[j] = input[j]; j++; for (int i = 1; i < elements; i++){ if (input[i] != input[i-1]){ output[j] = input[i]; j++; } } } int main(int argc, char **argv){ // Syntax verification if (argc != 4) { printf("Wrong format\n"); printf("Syntax: %s \n",argv[0]); exit(1); } int device = atoi(argv[1]); int input = atoi(argv[2]); int numElements = atoi(argv[3]); size_t size = numElements * sizeof(T); // Set device cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties,device); cudaSetDevice(device); printf("DS Unique on %s\n", device_properties.name); printf("Thread block size = %d\n", L_DIM); printf("Coarsening factor = %d\n", REGS); #ifdef FLOAT printf("Single precision array: %d elements\n", numElements); #elif INT printf("Integer array: %d elements\n", numElements); #else printf("Double precision array: %d elements\n", numElements); #endif // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; // Allocate the host input vector A T *h_A = (T*)malloc(size); // Allocate the host output vectors T *h_B = (T*)malloc(size); T *h_C = (T*)malloc(size); // Allocate the device input vector A T *d_A = NULL; cudaMalloc((void **)&d_A, size); #define WARMUP 0 #define REP 1 int value1 = 0; int value2 = 1; int value3 = 2; int value4 = 3; unsigned int flagM = 0; for(int iteration = 0; iteration < REP+WARMUP; iteration++){ // Initialize the host input vectors srand(2014); for(int i = 0; i < numElements; i++){ h_A[i] = value1; if(i >= numElements/4 && i < numElements/2) h_A[i] = value2; if(i >= numElements/2 && i < 3*numElements/4) h_A[i] = value3; if(i >= 3*numElements/4 && i < numElements) h_A[i] = value4; } int M = (numElements * input)/100; int m = M; while(m>0){ int x = (int)(numElements*(((float)rand()/(float)RAND_MAX))); if(h_A[x]==value1 || h_A[x]==value2 || h_A[x]==value3 || h_A[x]==value4){ h_A[x] = x+2; m--; } } #if PRINT printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_A+i)); } printf("\n"); #endif // Copy the host input vector A in host memory to the device input vector in device memory cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); int ldim = L_DIM; // Atomic flags unsigned int* d_flags = NULL; int num_flags = numElements % (ldim * REGS) == 0 ? numElements / (ldim * REGS) : numElements / (ldim * REGS) + 1; unsigned int *flags = (unsigned int *)calloc(sizeof(unsigned int), num_flags + 2); flags[0] = 1; flags[num_flags + 1] = 0; cudaMalloc((void **)&d_flags, (num_flags + 2) * sizeof(unsigned int)); cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); free(flags); // Number of work-groups/runtime blocks int num_wg = num_flags; // Start timer cudaEventRecord( start, 0 ); // Kernel launch unique<<>>(d_A, d_A, numElements, d_flags); cudaMemcpy(&flagM, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time2 += time1; if(iteration == REP+WARMUP-1){ float timer = time2 / REP; double bw = (double)((numElements + flagM) * sizeof(T)) / (double)(timer * 1000000.0); printf("Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Free flags cudaFree(d_flags); } // Copy to host memory cudaMemcpy(h_B, d_A, size, cudaMemcpyDeviceToHost); // CPU execution for comparison cpu_unique(h_C, h_A, numElements); // Verify that the result vector is correct #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_B+i)); } printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_C+i)); } printf("\n"); #endif for (int i = 0; i < flagM - 1; ++i){ if (h_B[i] != h_C[i]){ fprintf(stderr, "Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } printf("Test PASSED\n"); // Free device global memory cudaFree(d_A); cudaEventDestroy(start); cudaEventDestroy(stop); // Free host memory free(h_A); free(h_B); free(h_C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/UNI/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/UNI/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(UNI_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/UNI/dpu/task.c ================================================ /* * Unique with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets uint32_t message[NR_TASKLETS]; T message_value[NR_TASKLETS]; uint32_t message_offset[NR_TASKLETS]; uint32_t message_partial_count; T message_last_from_last; // UNI in each tasklet unsigned int __attribute__ ((noinline)) unique(T *output, T *input){ unsigned int pos = 0; output[pos] = input[pos]; pos++; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { if(input[j] != input[j - 1]) { output[pos] = input[j]; pos++; } } return pos; } // Handshake with adjacent tasklets uint3 __attribute__ ((noinline)) handshake_sync(T *output, unsigned int l_count, unsigned int tasklet_id){ unsigned int p_count, o_count, offset; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; offset = (message_value[tasklet_id] == output[0])?1:0; o_count = message_offset[tasklet_id]; } else{ p_count = 0; offset = (message_last_from_last == output[0])?1:0; o_count = 0; } // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; message_value[tasklet_id + 1] = output[l_count - 1]; message_offset[tasklet_id + 1] = o_count + offset; handshake_notify(); } uint3 result = {p_count, o_count, offset}; return result; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1){ message_partial_count = 0; message_last_from_last = 0xFFFFFFFF; // A value that is not in the input array } // Barrier barrier_wait(&my_barrier); unsigned int i = 0; // Iteration count for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // UNI in each tasklet unsigned int l_count = unique(cache_B, cache_A); // In-place or out-of-place? // Sync with adjacent tasklets uint3 po_count = handshake_sync(cache_B, l_count, tasklet_id); // Write cache to current MRAM block mram_write(&cache_B[po_count.z], (__mram_ptr void*)(mram_base_addr_B + (message_partial_count + po_count.x - po_count.y) * sizeof(T)), l_count * sizeof(T)); // First if(tasklet_id == 0 && i == 0){ result->first = cache_B[0]; } // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ message_last_from_last = cache_B[l_count - 1]; result->last = cache_B[l_count - 1]; result->t_count = message_partial_count + po_count.x + l_count - po_count.y - po_count.z; message_partial_count = result->t_count; } // Barrier barrier_wait(&my_barrier); i++; } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/UNI/host/app.c ================================================ /** * app.c * UNI Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static T* C; static T* C2; // Create input arrays static void read_input(T* A, unsigned int nr_elements, unsigned int nr_elements_round) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()); A[i] = i%2==0?i:i+1; } for (unsigned int i = nr_elements; i < nr_elements_round; i++) { A[i] = A[nr_elements - 1]; } } // Compute output in the host static unsigned int unique_host(T* C, T* A, unsigned int nr_elements) { unsigned int pos = 0; C[pos] = A[pos]; pos++; for(unsigned int i = 1; i < nr_elements; i++) { if(A[i] != A[i-1]) { C[pos] = A[i]; pos++; } } return pos; } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; uint32_t accum = 0; uint32_t total_count = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_dpu_ = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_round = (input_size_dpu_ % (NR_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NR_TASKLETS * REGS)) : input_size_dpu_; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data read_input(A, input_size, input_size_dpu_round * nr_of_dpus); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); total_count = unique_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments const unsigned int input_size_dpu = input_size_dpu_round; unsigned int kernel = 0; dpu_arguments_t input_arguments = {input_size_dpu * sizeof(T), kernel}; // Copy input arrays i = 0; DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, &input_arguments)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(input_arguments), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferA + input_size_dpu * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); dpu_results_t results[nr_of_dpus]; uint32_t* results_scan = malloc(nr_of_dpus * sizeof(uint32_t)); uint32_t* offset = calloc(nr_of_dpus, sizeof(uint32_t)); uint32_t* offset_scan = calloc(nr_of_dpus, sizeof(uint32_t)); i = 0; accum = 0; if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); // PARALLEL RETRIEVE TRANSFER dpu_results_t* results_retrieve[nr_of_dpus]; DPU_FOREACH(dpu_set, dpu, i) { results_retrieve[i] = (dpu_results_t*)malloc(NR_TASKLETS * sizeof(dpu_results_t)); DPU_ASSERT(dpu_prepare_xfer(dpu, results_retrieve[i])); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NR_TASKLETS * sizeof(dpu_results_t), DPU_XFER_DEFAULT)); DPU_FOREACH(dpu_set, dpu, i) { // Retrieve tasklet timings for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) { // First output element of this DPU if(each_tasklet == 0){ results[i].first = results_retrieve[i][each_tasklet].first; } // Last output element of this DPU and count if(each_tasklet == NR_TASKLETS - 1){ results[i].t_count = results_retrieve[i][each_tasklet].t_count; results[i].last = results_retrieve[i][each_tasklet].last; } } // Check if first(i) == last(i-1) -- offset if(i != 0){ if(results[i].first == results[i - 1].last) offset[i] = 1; // Sequential scan - offset offset_scan[i] += offset[i]; } // Sequential scan uint32_t temp = results[i].t_count - offset[i]; results_scan[i] = accum; accum += temp; #if PRINT printf("i=%d -- %u, %u, %u -- %u\n", i, results_scan[i], accum, temp, offset_scan[i]); #endif free(results_retrieve[i]); } if(rep >= p.n_warmup) stop(&timer, 3); i = 0; if(rep >= p.n_warmup) start(&timer, 4, rep - p.n_warmup); DPU_FOREACH (dpu_set, dpu) { // Copy output array DPU_ASSERT(dpu_copy_from(dpu, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(T), bufferC + results_scan[i] - offset_scan[i], results[i].t_count * sizeof(T))); i++; } if(rep >= p.n_warmup) stop(&timer, 4); // Free memory free(results_scan); free(offset); free(offset_scan); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("Inter-DPU "); print(&timer, 3, p.n_reps); printf("DPU-CPU "); print(&timer, 4, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; if(accum != total_count) status = false; #if PRINT printf("accum %u, total_count %u\n", accum, total_count); #endif for (i = 0; i < accum; i++) { if(C[i] != bufferC[i]){ status = false; #if PRINT printf("%d: %lu -- %lu\n", i, C[i], bufferC[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/UNI/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Data type #define T int64_t #define REGS (BLOCK_SIZE >> 3) // 64 bits // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; typedef struct { uint32_t t_count; T first; T last; } dpu_results_t; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif typedef struct{unsigned int x; unsigned int y; unsigned int z;} uint3; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/UNI/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/UNI/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/VA/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang/uPIMulator/benchmark/VA/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 TYPE ?= INT32 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o ${HOST_TARGET}.bin ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/cpu/Makefile ================================================ all: gcc -o va -fopenmp app_baseline.c clean: rm va ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/cpu/README ================================================ Vector addition (VA) Compilation instructions make Execution instructions ./va -t 4 ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/cpu/app_baseline.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" static int32_t *A; static int32_t *B; static int32_t *C; static int32_t *C2; /** * @brief creates a "test file" by filling a buffer of 64MB with pseudo-random values * @param nr_elements how many 32-bit elements we want the file to be * @return the buffer address */ void *create_test_file(unsigned int nr_elements) { srand(0); printf("nr_elements\t%u\t", nr_elements); A = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); B = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); C = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); for (int i = 0; i < nr_elements; i++) { A[i] = (int) (rand()); B[i] = (int) (rand()); } } /** * @brief compute output in the host */ static void vector_addition_host(unsigned int nr_elements, int t) { omp_set_num_threads(t); #pragma omp parallel for for (int i = 0; i < nr_elements; i++) { C[i] = A[i] + B[i]; } } // Params --------------------------------------------------------------------- typedef struct Params { int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16777216; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 5; int opt; while((opt = getopt(argc, argv, "hi:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; // Create an input file with arbitrary data. create_test_file(file_size); Timer timer; start(&timer, 0, 0); vector_addition_host(file_size, p.n_threads); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc vec_add.cu -I/usr/local/cuda/include -lm -o va clean: rm va ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/gpu/README ================================================ Vector addition (VA) Compilation instructions make Execution instructions ./va ================================================ FILE: golang/uPIMulator/benchmark/VA/baselines/gpu/vec_add.cu ================================================ /* File: vec_add.cu * Purpose: Implement vector addition on a gpu using cuda * * Compile: nvcc [-g] [-G] -o vec_add vec_add.cu * Run: ./vec_add */ #include #include #include #include __global__ void Vec_add(unsigned int x[], unsigned int y[], unsigned int z[], int n) { int thread_id = blockIdx.x * blockDim.x + threadIdx.x; if (thread_id < n){ z[thread_id] = x[thread_id] + y[thread_id]; } } int main(int argc, char* argv[]) { int n, m; unsigned int *h_x, *h_y, *h_z; unsigned int *d_x, *d_y, *d_z; size_t size; /* Define vector length */ n = 2621440; m = 320; size = m * n * sizeof(unsigned int); // Allocate memory for the vectors on host memory. h_x = (unsigned int*) malloc(size); h_y = (unsigned int*) malloc(size); h_z = (unsigned int*) malloc(size); for (int i = 0; i < n * m; i++) { h_x[i] = i+1; h_y[i] = n-i; } printf("Input size = %d\n", n * m); // Print original vectors. /*printf("h_x = "); for (int i = 0; i < m; i++){ printf("%u ", h_x[i]); } printf("\n\n"); printf("h_y = "); for (int i = 0; i < m; i++){ printf("%u ", h_y[i]); } printf("\n\n");*/ // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; /* Allocate vectors in device memory */ cudaMalloc(&d_x, size); cudaMalloc(&d_y, size); cudaMalloc(&d_z, size); /* Copy vectors from host memory to device memory */ cudaMemcpy(d_x, h_x, size, cudaMemcpyHostToDevice); cudaMemcpy(d_y, h_y, size, cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); /* Kernel Call */ Vec_add<<<(n * m) / 256, 256>>>(d_x, d_y, d_z, n * m); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); cudaMemcpy(h_z, d_z, size, cudaMemcpyDeviceToHost); /*printf("The sum is: \n"); for (int i = 0; i < m; i++){ printf("%u ", h_z[i]); } printf("\n");*/ printf("Execution time = %f ms\n", time1); /* Free device memory */ cudaFree(d_x); cudaFree(d_y); cudaFree(d_z); /* Free host memory */ free(h_x); free(h_y); free(h_z); return 0; } /* main */ ================================================ FILE: golang/uPIMulator/benchmark/VA/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT32) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/VA/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(VA_device ${SRCS}) ================================================ FILE: golang/uPIMulator/benchmark/VA/dpu/task.c ================================================ /* * Vector addition with multiple tasklets * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // vector_addition: Computes the vector addition of a cached block void __attribute__ ((noinline)) vector_addition(T *bufferB, T *bufferA, unsigned int l_size) { for (unsigned int i = 0; i < l_size; i++){ bufferB[i] += bufferA[i]; } } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); mram_read((__mram_ptr void const*)(mram_base_addr_B + byte_index), cache_B, l_size_bytes); // Computer vector addition vector_addition(cache_B, cache_A, l_size_bytes >> DIV); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), l_size_bytes); } return 0; } ================================================ FILE: golang/uPIMulator/benchmark/VA/host/app.c ================================================ /** * app.c * VA Host Application Source File * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/timer.h" #include "../support/params.h" // Define the DPU Binary path as DPU_BINARY here #ifndef DPU_BINARY #define DPU_BINARY "./bin/dpu_code" #endif #if ENERGY #include #endif // Pointer declaration static T* A; static T* B; static T* C; static T* C2; // Create input arrays static void read_input(T* A, T* B, unsigned int nr_elements) { srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { A[i] = (T) (rand()); B[i] = (T) (rand()); } } // Compute output in the host static void vector_addition_host(T* C, T* A, T* B, unsigned int nr_elements) { for (unsigned int i = 0; i < nr_elements; i++) { C[i] = A[i] + B[i]; } } // Main of the Host Application int main(int argc, char **argv) { struct Params p = input_params(argc, argv); struct dpu_set_t dpu_set, dpu; uint32_t nr_of_dpus; #if ENERGY struct dpu_probe_t probe; DPU_ASSERT(dpu_probe_init("energy_probe", &probe)); #endif // Allocate DPUs and load binary DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set)); DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL)); DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus)); printf("Allocated %d DPU(s)\n", nr_of_dpus); unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Total input size (weak or strong scaling) const unsigned int input_size_8bytes = ((input_size * sizeof(T)) % 8) != 0 ? roundup(input_size, 8) : input_size; // Input size per DPU (max.), 8-byte aligned const unsigned int input_size_dpu = divceil(input_size, nr_of_dpus); // Input size per DPU (max.) const unsigned int input_size_dpu_8bytes = ((input_size_dpu * sizeof(T)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; // Input size per DPU (max.), 8-byte aligned // Input/output allocation A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); B = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); C = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); C2 = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(T)); T *bufferA = A; T *bufferB = B; T *bufferC = C2; // Create an input file with arbitrary data read_input(A, B, input_size); // Timer declaration Timer timer; printf("NR_TASKLETS\t%d\tBL\t%d\n", NR_TASKLETS, BL); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); vector_addition_host(C, A, B, input_size); if(rep >= p.n_warmup) stop(&timer, 0); printf("Load input data\n"); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); // Input arguments unsigned int kernel = 0; dpu_arguments_t input_arguments[NR_DPUS]; for(i=0; i= p.n_warmup) stop(&timer, 1); printf("Run program on DPU(s) \n"); // Run DPU kernel if(rep >= p.n_warmup) { start(&timer, 2, rep - p.n_warmup); #if ENERGY DPU_ASSERT(dpu_probe_start(&probe)); #endif } DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS)); if(rep >= p.n_warmup) { stop(&timer, 2); #if ENERGY DPU_ASSERT(dpu_probe_stop(&probe)); #endif } #if PRINT { unsigned int each_dpu = 0; printf("Display DPU Logs\n"); DPU_FOREACH (dpu_set, dpu) { printf("DPU#%d:\n", each_dpu); DPU_ASSERT(dpulog_read_for_dpu(dpu.dpu, stdout)); each_dpu++; } } #endif printf("Retrieve results\n"); if(rep >= p.n_warmup) start(&timer, 3, rep - p.n_warmup); i = 0; // PARALLEL RETRIEVE TRANSFER DPU_FOREACH(dpu_set, dpu, i) { DPU_ASSERT(dpu_prepare_xfer(dpu, bufferC + input_size_dpu_8bytes * i)); } DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu_8bytes * sizeof(T), input_size_dpu_8bytes * sizeof(T), DPU_XFER_DEFAULT)); if(rep >= p.n_warmup) stop(&timer, 3); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("CPU-DPU "); print(&timer, 1, p.n_reps); printf("DPU Kernel "); print(&timer, 2, p.n_reps); printf("DPU-CPU "); print(&timer, 3, p.n_reps); #if ENERGY double energy; DPU_ASSERT(dpu_probe_get(&probe, DPU_ENERGY, DPU_AVERAGE, &energy)); printf("DPU Energy (J): %f\t", energy); #endif // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != bufferC[i]){ status = false; #if PRINT printf("%d: %u -- %u\n", i, C[i], bufferC[i]); #endif } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(B); free(C); free(C2); DPU_ASSERT(dpu_free(dpu_set)); return status ? 0 : -1; } ================================================ FILE: golang/uPIMulator/benchmark/VA/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; uint32_t transfer_size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang/uPIMulator/benchmark/VA/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=2621440 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2621440; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang/uPIMulator/benchmark/VA/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang/uPIMulator/benchmark/build.py ================================================ import os import shutil import subprocess import argparse if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--num_dpus", type=int, default=1) parser.add_argument("--num_tasklets", type=int, default=1) args = parser.parse_args() benchmark_dir_path = os.path.dirname(__file__) build_dir_path = os.path.join(benchmark_dir_path, "build") if os.path.exists(build_dir_path): shutil.rmtree(build_dir_path) os.makedirs(build_dir_path) subprocess.run( [ "cmake", "-D", f"NR_DPUS={args.num_dpus}", "-D" f"NR_TASKLETS={args.num_tasklets}", "-S", benchmark_dir_path, "-B", build_dir_path, "-G", "Ninja", ] ) subprocess.run(["ninja", "-C", build_dir_path]) ================================================ FILE: golang/uPIMulator/docker/Dockerfile ================================================ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt update RUN apt install -y git RUN apt install -y wget RUN apt install -y cmake RUN apt install -y ninja-build RUN apt install -y pkg-config RUN apt install -y python3 RUN apt install -y python3-pip # UPMEM SDK WORKDIR /root RUN wget sdk-releases.upmem.com/2023.2.0/ubuntu_22.04/upmem-2023.2.0-Linux-x86_64.tar.gz RUN tar -zxvf upmem-2023.2.0-Linux-x86_64.tar.gz RUN echo "source /root/upmem-2023.2.0-Linux-x86_64/upmem_env.sh" > /root/.bashrc WORKDIR /root/uPIMulator ================================================ FILE: golang/uPIMulator/go.mod ================================================ module uPIMulator go 1.21.5 ================================================ FILE: golang/uPIMulator/go.sum ================================================ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/dave/dst v0.27.3 h1:P1HPoMza3cMEquVf9kKy8yXsFirry4zEnWOdYPOoIzY= github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/segmentio/golines v0.11.0 h1:5NVrYkCBoe9wLerhTi+WFOlqx9g3PtP5Tm27uartkL0= github.com/segmentio/golines v0.11.0/go.mod h1:BRnGHV3is9Qs/58zOqy3CFwH1B2jdVsViGY3G+qctSs= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ================================================ FILE: golang/uPIMulator/script/build.py ================================================ import os import shutil import subprocess if __name__ == "__main__": script_dirpath = os.path.dirname(__file__) build_dirpath = os.path.join(script_dirpath, "..", "build") src_dirpath = os.path.join(script_dirpath, "..", "src") if os.path.exists(build_dirpath): shutil.rmtree(build_dirpath) os.makedirs(build_dirpath) binary_filepath = os.path.join(build_dirpath, "uPIMulator") subprocess.run(["go", "build", "-C", src_dirpath, "-o", binary_filepath]) ================================================ FILE: golang/uPIMulator/script/format.py ================================================ import os import subprocess if __name__ == "__main__": script_dirpath = os.path.dirname(__file__) src_dirpath = os.path.join(script_dirpath, "..", "src") subprocess.run(["gofmt", "-l", src_dirpath]) subprocess.run(["golines", "-w", src_dirpath]) ================================================ FILE: golang/uPIMulator/script/run_validation.sh ================================================ #/bin/bash root_dir=/home/via/dongjae/upimulator_beta/golang/uPIMulator eval "mkdir -p ${root_dir}/bin/" for num_tasklets in 1 2 4 8 16 do eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark BS --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 8192" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/BS_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "BS-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark GEMV --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 256" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/GEMV_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "GEMV-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark HST-L --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 32768" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/HST-L_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "HST-L-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark HST-S --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 32768" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/HST-S_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "HST-S-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark MLP --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 64" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/MLP_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "MLP-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark RED --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/RED_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "RED-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark SCAN-RSS --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/SCAN-RSS_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "SCAN-RSS-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark SCAN-SSA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/SCAN-SSA_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "SCAN-SSA-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark SEL --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/SEL_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "SEL-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark TRNS --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 128" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/TRNS_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "TRNS-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark TS --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 256" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/TS_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "TS-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark UNI --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/UNI_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "UNI-${num_tasklets} done \n" eval "${root_dir}/build/uPIMulator --root_dirpath ${root_dir}/ --bin_dirpath ${root_dir}/bin --benchmark VA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets ${num_tasklets} --data_prep_params 65536" eval "mv ${root_dir}/bin/log.txt ${root_dir}/validation_log/VA_${num_tasklets}.txt" eval "rm ${root_dir}/bin/*" echo "VA-${num_tasklets} done \n" done ================================================ FILE: golang/uPIMulator/script/visualize.py ================================================ import graphviz import os if __name__ == "__main__": script_dirpath = os.path.dirname(__file__) bin_dirpath = os.path.join(script_dirpath, "..", "bin") host_dirpath = os.path.join(bin_dirpath, "host") nodes_filepath = os.path.join(host_dirpath, "ast_nodes.txt") edges_filepath = os.path.join(host_dirpath, "ast_edges.txt") g = graphviz.Digraph(filename="ast", format="pdf", directory=host_dirpath) with open(nodes_filepath, "r") as f: for line in f.readlines(): node = line.strip() g.node(name=node) with open(edges_filepath, "r") as f: for line in f.readlines(): tail, head = line.split("->") tail = tail.strip() head = head.strip() g.edge(tail_name=tail, head_name=head) g.view() ================================================ FILE: golang/uPIMulator/sdk/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) project(sdk) add_subdirectory(misc) add_subdirectory(stdlib) add_subdirectory(syslib) ================================================ FILE: golang/uPIMulator/sdk/build.py ================================================ import os import shutil import subprocess import argparse if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--num_tasklets", type=int, default=1) args = parser.parse_args() sdk_dir_path = os.path.dirname(__file__) build_dir_path = os.path.join(sdk_dir_path, "build") if os.path.exists(build_dir_path): shutil.rmtree(build_dir_path) os.makedirs(build_dir_path) subprocess.run( [ "cmake", "-D", f"NR_TASKLETS={args.num_tasklets}", "-S", sdk_dir_path, "-B", build_dir_path, "-G", "Ninja", ] ) subprocess.run(["ninja", "-C", build_dir_path]) ================================================ FILE: golang/uPIMulator/sdk/misc/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(misc ${SRCS}) ================================================ FILE: golang/uPIMulator/sdk/misc/accessMramFromDpu.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { // Preconditions: // - MRAM offset is a multiple of 8 // - Buffer size is a multiple of 8 __asm__ volatile(" sd zero, 0, d0\n" // Saving context " sd zero, 8, d2\n" " or r0, zero, 0, ?xnz, . + 2\n" " or r0, r0, 0x2\n" " addc r0, r0, 0\n" " sw zero, 16, r0\n" " lw r0, zero, 20\n" // MRAM offset, must be patched by the Host "resume_start:\n" " lw r1, zero, 24\n" // Buffer size, must be patched by the Host " move r2, 32\n" // Wram offset " move r3, 2048\n" // Transfer size " transfer_loop:\n" " jltu r1, r3, last_transfer\n" " ldma r2, r0, 255\n" // Can be patched by the Host into a SDMA to write MRAM " add r0, r0, r3\n" " add r2, r2, r3\n" " sub r1, r1, r3, true, transfer_loop\n" "last_transfer:\n" " jz r1, end\n" " lsr r3, r1, 3\n" " add r3, r3, -1\n" " lsl_add r2, r2, r3, 24\n" " ldma r2, r0, 0\n" // Can be patched by the Host into a SDMA to write MRAM " add r0, r0, r1\n" "end:\n" " lw r2, zero, 28\n" // Restoring context if needed " jnz r2, . + 2\n" " stop true, resume_start\n" " ld d2, zero, 8\n" " lw r0, zero, 16\n" " add r1, r0, r0\n" " add r0, r0, r1\n" " call zero, r0, . + 1\n" " add r0, zero, 0x00000001; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 0, C = 0 " add r0, mneg, 0x80000001; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 0, C = 1 " add r0, zero, 0x00000000; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 1, C = 0 " add r0, mneg, 0x80000000; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 1, C = 1 ); } ================================================ FILE: golang/uPIMulator/sdk/misc/coreDump.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The "core dump" program, used by debugging processes to fetch each * runtime register and the atomic bits. * The program should be booted once on runtime 0. * * The output in WRAM has the following form: * - byte 0..255 = atomic bits : each bit is stored into an individual byte * - byte 256..2559 = work registers * - byte 2560..2555 = flags * * Only the runtime 0 fills in the atomic bits part of the output. */ #include "restore_carry_and_zero_flag.h" void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0), d0\n" " or r0, zero, 0, ?xnz, no_z_flag\n" " or r0, r0, 0x2\n" " no_z_flag:\n" " addc r0, r0, 0\n" " sw id4, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 12), r0\n" " jeq id, " __STR(NR_THREADS) " - 1, .+2\n" " boot id, 1\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 1), d2\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 2), d4\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 3), d6\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 4), d8\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 5), d10\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 6), d12\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 7), d14\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 8), d16\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 9), d18\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 10), d20\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 11), d22\n" " jnz id, atomic_done\n" " move r0, " __STR(NR_ATOMIC_BITS) " - 1\n" "atomic_loop:\n" " sb r0, 0, 0xFF\n" " acquire r0, 0, nz, atomic_next\n" " sb r0, 0, 0x00\n" " release r0, 0, nz, atomic_next\n" "atomic_next:\n" " add r0, r0, -1, pl, atomic_loop\n" "atomic_done:\n" RESTORE_CARRY_AND_ZERO_FLAG ); /* clang-format on */ } ================================================ FILE: golang/uPIMulator/sdk/misc/crt0.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include __mram_noinit uint8_t __sys_used_mram_end[0]; uint64_t __sys_null_pointer __attribute__((used, section(".data.__sys_zero"))) = 0ULL; uint32_t __lower_data("thread_profiling") thread_profiling[NR_THREADS]; uint32_t perfcounter_end_value; #define DECLARE_STACK(x) \ extern uint32_t __sys_stack_thread_##x; \ extern uint32_t STACK_SIZE_TASKLET_##x; #define SET_STACK_TABLE_PTR(x) \ [x] = { .stack_ptr = (uint32_t)&__sys_stack_thread_##x, .stack_size = (uint32_t)&STACK_SIZE_TASKLET_##x }, __FOR_EACH_THREAD(DECLARE_STACK); thread_stack_t __keep __dma_aligned __SP_TABLE__[NR_THREADS] = { __FOR_EACH_THREAD(SET_STACK_TABLE_PTR) }; __host const volatile uint32_t CLOCKS_PER_SEC; __host const volatile uint32_t error_storage; void __attribute__((naked, used, section(".text.__bootstrap"), no_instrument_function)) __bootstrap() { /* clang-format off */ __asm__ volatile( " jnz id, __sys_start_thread\n" __CONFIG_PERFCOUNTER_ENTRY__ " sd zero, " __STR(__STDOUT_BUFFER_STATE) ", 0\n" " move r23, " __STR(__atomic_end_addr) "\n" "__sys_atomic_bit_clear:\n" " jeq r23, " __STR(__atomic_used_addr) ", __sys_start_thread\n" " release r23, 0, nz, . + 1\n" " add r23, r23, -1, true, __sys_atomic_bit_clear\n" "__sys_start_thread:\n" " jeq id, NR_TASKLETS - 1, . + 2\n" " boot id, 1\n" " ld d22, id8, " __STR(__SP_TABLE__) "\n" " call r23, main\n" ".globl __sys_end\n" "__sys_end:\n" __SAVE_PERFCOUNTER_ENTRY__ " stop true, __sys_end"); /* clang-format on */ } ================================================ FILE: golang/uPIMulator/sdk/misc/dpu.lds ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Default linker script for DPU programs. * The bootstrap sequence is generated by the studio as __bootstrap. * The two DPU memories (IRAM and WRAM) are mapped on two different * "virtual" spaces: * - IRAM: starts at address 0x80000000, which may imply fixups * when loading and debugging of programs * - WRAM: exposed as is at address 0x00000000 * * In addition, the run-time environment information is stored into * a virtual physical space at 0x40000000. */ ENTRY(__bootstrap) MEMORY { iram (rx) : ORIGIN = 0x80000000, LENGTH = 32K mram (wa) : ORIGIN = 0x08000000, LENGTH = 64M wram (wa) : ORIGIN = 0x00000000, LENGTH = 64K atomic (r) : ORIGIN = 0xF0000000, LENGTH = 256 } SECTIONS { /* * Merge every text section into .text. */ .text : { *(.text.__bootstrap) *(.text) *(.text.*) } > iram /* * Atomic bits 'allocator' */ .atomic (NOLOAD) : { __atomic_start_addr = .; . = . + 200; __atomic_used_addr = .; *(.atomic) __atomic_end_addr = .; } > atomic /* * Locate every other section as data. */ .data : { KEEP(*(.data.__sys_zero)) . += MAX(8, .); /* WRAM accessible using loads and stores with immediate 11-bit offsets */ *(.data.immediate_memory .data.immediate_memory.*) HIDDEN(__imm_mem_end = .); ASSERT(__imm_mem_end < 2048, "immediate memory not accessible with 11-bit address") __rodata_start_addr = .; *(.rodata .rodata.*) __rodata_end_addr = .; *(.bss .bss.*) *(COMMON) /* Data that we want to keep even there seems to be no use, * usually because host may need it. */ KEEP(*(.data.__sys_keep)) *(.data .data.*) . = ALIGN(8); } > wram .data.__sys_host : { . = ALIGN(8); KEEP(*(.dpu_host)) } > wram .data.__sys_profiling : { . = ALIGN(4); KEEP(*(.dpu_profiling)) } > wram .data.stacks (NOLOAD) : { ASSERT(NR_TASKLETS >= 0 && NR_TASKLETS <= 24, "NR_TASKLETS should be in the range: [0; 24]") ASSERT(((STACK_SIZE_TASKLET_0 % 8 == 0) && (STACK_SIZE_TASKLET_0 > 0)) || (NR_TASKLETS <= 0 ), "STACK_SIZE_TASKLET_0 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_1 % 8 == 0) && (STACK_SIZE_TASKLET_1 > 0)) || (NR_TASKLETS <= 1 ), "STACK_SIZE_TASKLET_1 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_2 % 8 == 0) && (STACK_SIZE_TASKLET_2 > 0)) || (NR_TASKLETS <= 2 ), "STACK_SIZE_TASKLET_2 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_3 % 8 == 0) && (STACK_SIZE_TASKLET_3 > 0)) || (NR_TASKLETS <= 3 ), "STACK_SIZE_TASKLET_3 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_4 % 8 == 0) && (STACK_SIZE_TASKLET_4 > 0)) || (NR_TASKLETS <= 4 ), "STACK_SIZE_TASKLET_4 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_5 % 8 == 0) && (STACK_SIZE_TASKLET_5 > 0)) || (NR_TASKLETS <= 5 ), "STACK_SIZE_TASKLET_5 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_6 % 8 == 0) && (STACK_SIZE_TASKLET_6 > 0)) || (NR_TASKLETS <= 6 ), "STACK_SIZE_TASKLET_6 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_7 % 8 == 0) && (STACK_SIZE_TASKLET_7 > 0)) || (NR_TASKLETS <= 7 ), "STACK_SIZE_TASKLET_7 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_8 % 8 == 0) && (STACK_SIZE_TASKLET_8 > 0)) || (NR_TASKLETS <= 8 ), "STACK_SIZE_TASKLET_8 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_9 % 8 == 0) && (STACK_SIZE_TASKLET_9 > 0)) || (NR_TASKLETS <= 9 ), "STACK_SIZE_TASKLET_9 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_10 % 8 == 0) && (STACK_SIZE_TASKLET_10 > 0)) || (NR_TASKLETS <= 10), "STACK_SIZE_TASKLET_10 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_11 % 8 == 0) && (STACK_SIZE_TASKLET_11 > 0)) || (NR_TASKLETS <= 11), "STACK_SIZE_TASKLET_11 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_12 % 8 == 0) && (STACK_SIZE_TASKLET_12 > 0)) || (NR_TASKLETS <= 12), "STACK_SIZE_TASKLET_12 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_13 % 8 == 0) && (STACK_SIZE_TASKLET_13 > 0)) || (NR_TASKLETS <= 13), "STACK_SIZE_TASKLET_13 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_14 % 8 == 0) && (STACK_SIZE_TASKLET_14 > 0)) || (NR_TASKLETS <= 14), "STACK_SIZE_TASKLET_14 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_15 % 8 == 0) && (STACK_SIZE_TASKLET_15 > 0)) || (NR_TASKLETS <= 15), "STACK_SIZE_TASKLET_15 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_16 % 8 == 0) && (STACK_SIZE_TASKLET_16 > 0)) || (NR_TASKLETS <= 16), "STACK_SIZE_TASKLET_16 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_17 % 8 == 0) && (STACK_SIZE_TASKLET_17 > 0)) || (NR_TASKLETS <= 17), "STACK_SIZE_TASKLET_17 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_18 % 8 == 0) && (STACK_SIZE_TASKLET_18 > 0)) || (NR_TASKLETS <= 18), "STACK_SIZE_TASKLET_18 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_19 % 8 == 0) && (STACK_SIZE_TASKLET_19 > 0)) || (NR_TASKLETS <= 19), "STACK_SIZE_TASKLET_19 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_20 % 8 == 0) && (STACK_SIZE_TASKLET_20 > 0)) || (NR_TASKLETS <= 20), "STACK_SIZE_TASKLET_20 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_21 % 8 == 0) && (STACK_SIZE_TASKLET_21 > 0)) || (NR_TASKLETS <= 21), "STACK_SIZE_TASKLET_21 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_22 % 8 == 0) && (STACK_SIZE_TASKLET_22 > 0)) || (NR_TASKLETS <= 22), "STACK_SIZE_TASKLET_22 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_23 % 8 == 0) && (STACK_SIZE_TASKLET_23 > 0)) || (NR_TASKLETS <= 23), "STACK_SIZE_TASKLET_23 should be a multiple of 8 and > 0") ASSERT((NR_TASKLETS > 0 ) || (STACK_SIZE_TASKLET_0 == 0) , "STACK_SIZE_TASKLET_0 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 1 ) || (STACK_SIZE_TASKLET_1 == 0) , "STACK_SIZE_TASKLET_1 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 2 ) || (STACK_SIZE_TASKLET_2 == 0) , "STACK_SIZE_TASKLET_2 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 3 ) || (STACK_SIZE_TASKLET_3 == 0) , "STACK_SIZE_TASKLET_3 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 4 ) || (STACK_SIZE_TASKLET_4 == 0) , "STACK_SIZE_TASKLET_4 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 5 ) || (STACK_SIZE_TASKLET_5 == 0) , "STACK_SIZE_TASKLET_5 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 6 ) || (STACK_SIZE_TASKLET_6 == 0) , "STACK_SIZE_TASKLET_6 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 7 ) || (STACK_SIZE_TASKLET_7 == 0) , "STACK_SIZE_TASKLET_7 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 8 ) || (STACK_SIZE_TASKLET_8 == 0) , "STACK_SIZE_TASKLET_8 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 9 ) || (STACK_SIZE_TASKLET_9 == 0) , "STACK_SIZE_TASKLET_9 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 10) || (STACK_SIZE_TASKLET_10 == 0) , "STACK_SIZE_TASKLET_10 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 11) || (STACK_SIZE_TASKLET_11 == 0) , "STACK_SIZE_TASKLET_11 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 12) || (STACK_SIZE_TASKLET_12 == 0) , "STACK_SIZE_TASKLET_12 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 13) || (STACK_SIZE_TASKLET_13 == 0) , "STACK_SIZE_TASKLET_13 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 14) || (STACK_SIZE_TASKLET_14 == 0) , "STACK_SIZE_TASKLET_14 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 15) || (STACK_SIZE_TASKLET_15 == 0) , "STACK_SIZE_TASKLET_15 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 16) || (STACK_SIZE_TASKLET_16 == 0) , "STACK_SIZE_TASKLET_16 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 17) || (STACK_SIZE_TASKLET_17 == 0) , "STACK_SIZE_TASKLET_17 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 18) || (STACK_SIZE_TASKLET_18 == 0) , "STACK_SIZE_TASKLET_18 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 19) || (STACK_SIZE_TASKLET_19 == 0) , "STACK_SIZE_TASKLET_19 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 20) || (STACK_SIZE_TASKLET_20 == 0) , "STACK_SIZE_TASKLET_20 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 21) || (STACK_SIZE_TASKLET_21 == 0) , "STACK_SIZE_TASKLET_21 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 22) || (STACK_SIZE_TASKLET_22 == 0) , "STACK_SIZE_TASKLET_22 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 23) || (STACK_SIZE_TASKLET_23 == 0) , "STACK_SIZE_TASKLET_23 should be equal to 0 as the tasklet is not active") . = ALIGN(8); __sys_stack_thread_0 = .; . += STACK_SIZE_TASKLET_0; __sys_stack_thread_1 = .; . += STACK_SIZE_TASKLET_1; __sys_stack_thread_2 = .; . += STACK_SIZE_TASKLET_2; __sys_stack_thread_3 = .; . += STACK_SIZE_TASKLET_3; __sys_stack_thread_4 = .; . += STACK_SIZE_TASKLET_4; __sys_stack_thread_5 = .; . += STACK_SIZE_TASKLET_5; __sys_stack_thread_6 = .; . += STACK_SIZE_TASKLET_6; __sys_stack_thread_7 = .; . += STACK_SIZE_TASKLET_7; __sys_stack_thread_8 = .; . += STACK_SIZE_TASKLET_8; __sys_stack_thread_9 = .; . += STACK_SIZE_TASKLET_9; __sys_stack_thread_10 = .; . += STACK_SIZE_TASKLET_10; __sys_stack_thread_11 = .; . += STACK_SIZE_TASKLET_11; __sys_stack_thread_12 = .; . += STACK_SIZE_TASKLET_12; __sys_stack_thread_13 = .; . += STACK_SIZE_TASKLET_13; __sys_stack_thread_14 = .; . += STACK_SIZE_TASKLET_14; __sys_stack_thread_15 = .; . += STACK_SIZE_TASKLET_15; __sys_stack_thread_16 = .; . += STACK_SIZE_TASKLET_16; __sys_stack_thread_17 = .; . += STACK_SIZE_TASKLET_17; __sys_stack_thread_18 = .; . += STACK_SIZE_TASKLET_18; __sys_stack_thread_19 = .; . += STACK_SIZE_TASKLET_19; __sys_stack_thread_20 = .; . += STACK_SIZE_TASKLET_20; __sys_stack_thread_21 = .; . += STACK_SIZE_TASKLET_21; __sys_stack_thread_22 = .; . += STACK_SIZE_TASKLET_22; __sys_stack_thread_23 = .; . += STACK_SIZE_TASKLET_23; . = ALIGN(8); } > wram .data.sw_cache (NOLOAD): { . = ALIGN(8); __sw_cache_buffer = .; . += 8 * NR_TASKLETS; } > wram .data.heap_pointer_reset (NOLOAD) : { /* Start of heap: must be aligned on DMA size. * Stored as a symbol "__reset_heap_pointer", so that * the bootstrap just moves the value into a register to * initialize heap pointer at each reboot. */ . = ALIGN(8); PROVIDE(__sys_heap_pointer_reset = .); } > wram .mram.noinit (NOLOAD) : { *(.mram.noinit .mram.noinit.*) KEEP(*(.mram.noinit.keep .mram.noinit.keep.*)) } > mram .mram : { *(.mram .mram.*) KEEP(*(.mram.keep .mram.keep.*)) . = ALIGN(8); __sys_used_mram_end = .; } > mram } ================================================ FILE: golang/uPIMulator/sdk/misc/internalStateReset.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The strict minimum to reset the internal state of the DPU (that can only be changed by a DPU program). */ #define __STR(x) __STR_AGAIN(x) #define __STR_AGAIN(x) #x void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " sub r0, " __STR(NR_ATOMIC_BITS) " - 1, id\n" "before_release:\n" // Resetting Atomic bits " release r0, 0, nz, after_release\n" "after_release:\n" " sub r0, r0, " __STR(NR_THREADS) ", pl, before_release\n" // Resetting Zero and Carry flags + Preparing configuration for perfcounter register " add r0, zero, 7\n" // Resetting Performance Counter " time_cfg zero, r0\n" // Resetting Pc " stop true, 0\n"); /* clang-format on */ } ================================================ FILE: golang/uPIMulator/sdk/misc/linkerScript.lds ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Simple linker script for embedded programs. */ ENTRY(__bootstrap) MEMORY { iram (rx) : ORIGIN = 0x80000000, LENGTH = 32K } SECTIONS { /* * Merge every text section into .text. */ .text : { *(.text) } > iram } ================================================ FILE: golang/uPIMulator/sdk/misc/restoreRegisters.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The "restore registers" program, is used by debugging processes to restore every registers of every runtime. * The program should be booted once on runtime 0. */ #include "restore_carry_and_zero_flag.h" void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " jeq id, " __STR(NR_THREADS) " - 1, .+2\n" " boot id, 1\n" " ld d2, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 1)\n" " ld d4, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 2)\n" " ld d6, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 3)\n" " ld d8, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 4)\n" " ld d10, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 5)\n" " ld d12, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 6)\n" " ld d14, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 7)\n" " ld d16, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 8)\n" " ld d18, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 9)\n" " ld d20, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 10)\n" " ld d22, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 11)\n" " jnz id, atomic_done\n" " move r0, " __STR(NR_ATOMIC_BITS) " - 1\n" "atomic_loop:\n" " lbu r1, r0, 0\n" " jz r1, atomic_release\n" " acquire r0, 0, true, atomic_next\n" "atomic_release:\n" " release r0, 0, nz, atomic_next\n" "atomic_next:\n" " add r0, r0, -1, pl, atomic_loop\n" "atomic_done:\n" RESTORE_CARRY_AND_ZERO_FLAG ); /* clang-format on */ } ================================================ FILE: golang/uPIMulator/sdk/misc/restore_carry_and_zero_flag.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "macro_utils.h" /* clang-format off */ #define __RESTORE_CARRY_AND_ZERO_FLAG(x) \ "add r0, zero, 0x00000001; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 0, C = 0 */ \ "add r0, mneg, 0x80000001; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 0, C = 1 */ \ "add r0, zero, 0x00000000; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 1, C = 0 */ \ "add r0, mneg, 0x80000000; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" // ... restore Z = 1, C = 1 */ #define RESTORE_CARRY_AND_ZERO_FLAG \ " lw r0, id4, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 12)\n" \ " add r1, r0, r0\n" \ " add r0, r0, r1\n" /* r0 = 3 * r0 (each line of ending_routines is 3 instructions) */ \ " or r1, id8, 0 \n" \ " add r1, id4, r1\n" /* r1 = 12 * id (there are 12 instructions per runtime in ending_routines) */ \ " add r0, r0, r1\n" /* r0 = r0 + r1 (compute the offset (in number of instructions) to jump to) */ \ " call zero, r0, ending_routines\n" \ "ending_routines:\n" \ __FOR_EACH_THREAD(__RESTORE_CARRY_AND_ZERO_FLAG) /* clang-format on */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(stdlib ${SRCS}) ================================================ FILE: golang/uPIMulator/sdk/stdlib/abort.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void abort() { halt(); } ================================================ FILE: golang/uPIMulator/sdk/stdlib/assert.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ASSERT_H_ #define _DPUSYSCORE_ASSERT_H_ /** * @file assert.h * @brief Provides a way to verify assumptions with assert. */ #define static_assert _Static_assert #ifdef NDEBUG /** * @def assert * @hideinitializer * @brief When NDEBUG is defined, assert is not available and calling it will do nothing. */ #define assert(ignore) ((void)0) #else #include #include /** * @def assert * @hideinitializer * @brief Verify the assumption of the specified expression, resulting in a fault if it fails. * * @param expression the assumption to verify * @throws FAULT_ASSERT_FAILED when the assertion failed * @todo add a diagnostic message to the log, if it exists, when the assertion fails */ #define assert(expression) \ do { \ if (!(expression)) { \ __asm__ volatile("fault " __STR(__FAULT_ASSERT_FAILED__)); \ } \ } while (0) #endif /* NDEBUG */ #endif /* _DPUSYSCORE_ASSERT_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/atoi.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include int atoi(const char *nptr) { int result = 0; bool is_positive = true; if (nptr == NULL) { return result; } while (isspace(*nptr)) { nptr++; } if (*nptr == '-') { is_positive = false; nptr++; } else if (*nptr == '+') { nptr++; } for (;; nptr++) { unsigned int digit = *nptr - '0'; if (digit > 9) { break; } result = (10 * result) + digit; } return is_positive ? result : -result; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/atol.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include long atol(const char *nptr) { long result = 0; bool is_positive = true; if (nptr == NULL) { return result; } while (isspace(*nptr)) { nptr++; } if (*nptr == '-') { is_positive = false; nptr++; } else if (*nptr == '+') { nptr++; } for (;; nptr++) { unsigned int digit = *nptr - '0'; if (digit > 9) { break; } result = (10 * result) + digit; } return is_positive ? result : -result; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/ctype.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_CTYPE_H_ #define _DPUSYSCORE_CTYPE_H_ /** * @file ctype.h * @brief Provides useful functions for testing and mapping characters. */ /** * @brief Checks whether the specified character is a digit. * @param c an unsigned char or EOF * @return Whether the character is a digit (using 0 as false and anything else as true). */ static inline int isdigit(int c) { return (c >= '0') && (c <= '9'); } /** * @brief Checks whether the specified character is a lowercase letter. * @param c an unsigned char or EOF * @return Whether the character is a digit (using 0 as false and anything else as true). */ static inline int islower(c) { return (c >= 'a') && (c <= 'z'); } /** * @brief Checks whether the specified character is an uppercase letter. * @param c an unsigned char or EOF * @return Whether the character is an uppercase letter (using 0 as false and anything else as true). */ static inline int isupper(c) { return (c >= 'A') && (c <= 'Z'); } /** * @brief Checks whether the specified character is a letter. * @param c an unsigned char or EOF * @return Whether the character is a letter (using 0 as false and anything else as true). */ static inline int isalpha(int c) { return islower(c) || isupper(c); } /** * @brief Checks whether the specified character is a letter or a digit. * @param c an unsigned char or EOF * @return Whether the character is a letter or a digit (using 0 as false and anything else as true). */ static inline int isalnum(int c) { return isalpha(c) || isdigit(c); } /** * @brief Checks whether the specified character is a control character. * @param c an unsigned char or EOF * @return Whether the character is a control character (using 0 as false and anything else as true). */ static inline int iscntrl(int c) { return (c <= 0x1f) || (c == 0x7f); } /** * @brief Checks whether the specified character is printable. * @param c an unsigned char or EOF * @return Whether the character is printable (using 0 as false and anything else as true). */ static inline int isprint(int c) { return !iscntrl(c); } /** * @brief Checks whether the specified character has graphical representation using locale. * @param c an unsigned char or EOF * @return Whether the character has graphical representation using locale (using 0 as false and anything else as true). */ static inline int isgraph(int c) { return isprint(c) && (c != ' '); } /** * @brief Checks whether the specified character is a punctuation character. * @param c an unsigned char or EOF * @return Whether the character is a punctuation character (using 0 as false and anything else as true). */ static inline int ispunct(int c) { return (c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~'); } /** * @brief Checks whether the specified character is a white-space. * @param c an unsigned char or EOF * @return Whether the character is a white-space (using 0 as false and anything else as true). */ static inline int isspace(int c) { return (c >= 0x9 && c <= 0xd) || (c == ' '); } /** * @brief Checks whether the specified character is a hexadecimal digit. * @param c an unsigned char or EOF * @return Whether the character is a hexadecimal digit (using 0 as false and anything else as true). */ static inline int isxdigit(int c) { return isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } /** * @brief Checks whether the specified character is a blank character. * @param c an unsigned char or EOF * @return Whether the character is a blank character (using 0 as false and anything else as true). */ static inline int isblank(int c) { return c == ' ' || c == '\t'; } /** * @brief Converts the specified character to a lowercase letter if it is a letter; * @param c an unsigned char or EOF * @return The lowercase letter corresponding to the character, if it is a letter. The initial character otherwise. */ static inline int tolower(int c) { return isupper(c) ? (c + 0x20) : c; } /** * @brief Converts the specified character to a uppercase letter if it is a letter; * @param c an unsigned char or EOF * @return The uppercase letter corresponding to the character, if it is a letter. The initial character otherwise. */ static inline int toupper(int c) { return islower(c) ? (c - 0x20) : c; } #endif /* _DPUSYSCORE_CTYPE_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/errno.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ int __errno[NR_THREADS]; ================================================ FILE: golang/uPIMulator/sdk/stdlib/errno.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ERRNO_H_ #define _DPUSYSCORE_ERRNO_H_ #include /** * @file errno.h * @brief Defines the system error numbers. */ // errno is an array indexed on the tasklet id rather than // a single integer. extern int __errno[]; // Mimic errno variable as an index to __errno. // Defined in such a way that users can't override errno. #define errno (*(__errno + me())) /** * @def E2BIG * @brief Argument list too long. */ #define E2BIG 1 /** * @def EACCES * @brief Permission denied. */ #define EACCES 2 /** * @def EADDRINUSE * @brief Address in use. */ #define EADDRINUSE 3 /** * @def EADDRNOTAVAIL * @brief Address not available. */ #define EADDRNOTAVAIL 4 /** * @def EAFNOSUPPORT * @brief Address family not supported. */ #define EAFNOSUPPORT 5 /** * @def EAGAIN * @brief Resource unavailable, try again. */ #define EAGAIN 6 /** * @def EALREADY * @brief Connection already in progress. */ #define EALREADY 7 /** * @def EBADF * @brief Bad file descriptor. */ #define EBADF 8 /** * @def EBADMSG * @brief Bad message. */ #define EBADMSG 9 /** * @def EBUSY * @brief Device or resource busy. */ #define EBUSY 10 /** * @def ECANCELED * @brief Operation canceled. */ #define ECANCELED 11 /** * @def ECHILD * @brief No child processes. */ #define ECHILD 12 /** * @def ECONNABORTED * @brief Connection aborted. */ #define ECONNABORTED 13 /** * @def ECONNREFUSED * @brief Connection refused. */ #define ECONNREFUSED 14 /** * @def ECONNRESET * @brief Connection reset. */ #define ECONNRESET 15 /** * @def EDEADLK * @brief Resource deadlock would occur. */ #define EDEADLK 16 /** * @def EDESTADDRREQ * @brief Destination address required. */ #define EDESTADDRREQ 17 /** * @def EDOM * @brief Mathematics argument out of domain of function. */ #define EDOM 18 /** * @def EDQUOT * @brief Reserved. */ #define EDQUOT 19 /** * @def EEXIST * @brief File exists. */ #define EEXIST 20 /** * @def EFAULT * @brief Bad address. */ #define EFAULT 21 /** * @def EFBIG * @brief File too large. */ #define EFBIG 22 /** * @def EHOSTUNREACH * @brief Host is unreachable. */ #define EHOSTUNREACH 23 /** * @def EIDRM * @brief Identifier removed. */ #define EIDRM 24 /** * @def EILSEQ * @brief Illegal byte sequence. */ #define EILSEQ 25 /** * @def EINPROGRESS * @brief Operation in progress. */ #define EINPROGRESS 26 /** * @def EINTR * @brief Interrupted function. */ #define EINTR 27 /** * @def EINVAL * @brief Invalid argument. */ #define EINVAL 28 /** * @def EIO * @brief I/O error. */ #define EIO 29 /** * @def EISCONN * @brief Socket is connected. */ #define EISCONN 30 /** * @def EISDIR * @brief Is a directory. */ #define EISDIR 31 /** * @def ELOOP * @brief Too many levels of symbolic links. */ #define ELOOP 32 /** * @def EMFILE * @brief File descriptor value too large. */ #define EMFILE 33 /** * @def EMLINK * @brief Too many links. */ #define EMLINK 34 /** * @def EMSGSIZE * @brief Message too large. */ #define EMSGSIZE 35 /** * @def EMULTIHOP * @brief Reserved. */ #define EMULTIHOP 36 /** * @def ENAMETOOLONG * @brief Filename too long. */ #define ENAMETOOLONG 37 /** * @def ENETDOWN * @brief Network is down. */ #define ENETDOWN 38 /** * @def ENETRESET * @brief Connection aborted by network. */ #define ENETRESET 39 /** * @def ENETUNREACH * @brief Network unreachable. */ #define ENETUNREACH 40 /** * @def ENFILE * @brief Too many files open in system. */ #define ENFILE 41 /** * @def ENOBUFS * @brief No buffer space available. */ #define ENOBUFS 42 /** * @def ENODATA * @brief No message is available on the STREAM head read queue. */ #define ENODATA 43 /** * @def ENODEV * @brief No such device. */ #define ENODEV 44 /** * @def ENOENT * @brief No such file or directory. */ #define ENOENT 45 /** * @def ENOEXEC * @brief Executable file format error. */ #define ENOEXEC 46 /** * @def ENOLCK * @brief No locks available. */ #define ENOLCK 47 /** * @def ENOLINK * @brief Reserved. */ #define ENOLINK 48 /** * @def ENOMEM * @brief Not enough space. */ #define ENOMEM 49 /** * @def ENOMSG * @brief No message of the desired type. */ #define ENOMSG 50 /** * @def ENOPROTOOPT * @brief Protocol not available. */ #define ENOPROTOOPT 51 /** * @def ENOSPC * @brief No space left on device. */ #define ENOSPC 52 /** * @def ENOSR * @brief No STREAM resources. */ #define ENOSR 53 /** * @def ENOSTR * @brief Not a STREAM. */ #define ENOSTR 54 /** * @def ENOSYS * @brief Function not supported. */ #define ENOSYS 55 /** * @def ENOTCONN * @brief The socket is not connected. */ #define ENOTCONN 56 /** * @def ENOTDIR * @brief Not a directory or a symbolic link to a directory. */ #define ENOTDIR 57 /** * @def ENOTEMPTY * @brief Directory not empty. */ #define ENOTEMPTY 58 /** * @def ENOTRECOVERABLE * @brief State not recoverable. */ #define ENOTRECOVERABLE 59 /** * @def ENOTSOCK * @brief Not a socket. */ #define ENOTSOCK 60 /** * @def ENOTSUP * @brief Not supported. */ #define ENOTSUP 61 /** * @def ENOTTY * @brief Inappropriate I/O control operation. */ #define ENOTTY 62 /** * @def ENXIO * @brief No such device or address. */ #define ENXIO 63 /** * @def EOPNOTSUPP * @brief Operation not supported on socket. */ #define EOPNOTSUPP ENOTSUP /** * @def EOVERFLOW * @brief Value too large to be stored in data type. */ #define EOVERFLOW 65 /** * @def EOWNERDEAD * @brief Previous owner died. */ #define EOWNERDEAD 66 /** * @def EPERM * @brief Operation not permitted. */ #define EPERM 67 /** * @def EPIPE * @brief Broken pipe. */ #define EPIPE 68 /** * @def EPROTO * @brief Protocol error. */ #define EPROTO 69 /** * @def EPROTONOSUPPORT * @brief Protocol not supported. */ #define EPROTONOSUPPORT 70 /** * @def EPROTOTYPE * @brief Protocol wrong type for socket. */ #define EPROTOTYPE 71 /** * @def ERANGE * @brief Result too large. */ #define ERANGE 72 /** * @def EROFS * @brief Read-only file system. */ #define EROFS 73 /** * @def ESPIPE * @brief Invalid seek. */ #define ESPIPE 74 /** * @def ESRCH * @brief No such process. */ #define ESRCH 75 /** * @def ESTALE * @brief Reserved. */ #define ESTALE 76 /** * @def ETIME * @brief Stream ioctl() timeout. */ #define ETIME 77 /** * @def ETIMEDOUT * @brief Connection timed out. */ #define ETIMEDOUT 78 /** * @def ETXTBSY * @brief Text file busy. */ #define ETXTBSY 79 /** * @def EWOULDBLOCK * @brief Operation would block. */ #define EWOULDBLOCK ENOTSUP /** * @def EXDEV * @brief Cross-device link. */ #define EXDEV 81 #endif /* _DPUSYSCORE_ERRNO_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/exit.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "defs.h" #include "stdlib.h" #define unreachable() __builtin_unreachable() void exit(int __attribute__((unused)) status) { __asm__ volatile("stop true, __sys_end"); unreachable(); } ================================================ FILE: golang/uPIMulator/sdk/stdlib/inttypes.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_INTTYPES_H_ #define _DPUSYSCORE_INTTYPES_H_ /** * @file inttypes.h * @brief Extends stdint.h. */ #include typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; static inline intmax_t imaxabs(intmax_t x) { return (x < 0) ? -x : x; } static inline imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) { imaxdiv_t result = { numer / denom, numer % denom }; return result; } /* Macros for printing format specifiers. */ /* Decimal notation. */ #define PRId8 "d" #define PRId16 "d" #define PRId32 "d" #define PRId64 "ld" #define PRIdLEAST8 "d" #define PRIdLEAST16 "d" #define PRIdLEAST32 "d" #define PRIdLEAST64 "ld" #define PRIdFAST8 "d" #define PRIdFAST16 "d" #define PRIdFAST32 "d" #define PRIdFAST64 "ld" #define PRIi8 "i" #define PRIi16 "i" #define PRIi32 "i" #define PRIi64 "li" #define PRIiLEAST8 "i" #define PRIiLEAST16 "i" #define PRIiLEAST32 "i" #define PRIiLEAST64 "li" #define PRIiFAST8 "i" #define PRIiFAST16 "i" #define PRIiFAST32 "i" #define PRIiFAST64 "li" /* Octal notation. */ #define PRIo8 "o" #define PRIo16 "o" #define PRIo32 "o" #define PRIo64 "lo" #define PRIoLEAST8 "o" #define PRIoLEAST16 "o" #define PRIoLEAST32 "o" #define PRIoLEAST64 "lo" #define PRIoFAST8 "o" #define PRIoFAST16 "o" #define PRIoFAST32 "o" #define PRIoFAST64 "lo" /* Unsigned integers. */ #define PRIu8 "u" #define PRIu16 "u" #define PRIu32 "u" #define PRIu64 "lu" #define PRIuLEAST8 "u" #define PRIuLEAST16 "u" #define PRIuLEAST32 "u" #define PRIuLEAST64 "lu" #define PRIuFAST8 "u" #define PRIuFAST16 "u" #define PRIuFAST32 "u" #define PRIuFAST64 "lu" /* lowercase hexadecimal notation. */ #define PRIx8 "x" #define PRIx16 "x" #define PRIx32 "x" #define PRIx64 "lx" #define PRIxLEAST8 "x" #define PRIxLEAST16 "x" #define PRIxLEAST32 "x" #define PRIxLEAST64 "lx" #define PRIxFAST8 "x" #define PRIxFAST16 "x" #define PRIxFAST32 "x" #define PRIxFAST64 "lx" /* UPPERCASE hexadecimal notation. */ #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "X" #define PRIX64 "lX" #define PRIXLEAST8 "X" #define PRIXLEAST16 "X" #define PRIXLEAST32 "X" #define PRIXLEAST64 "lX" #define PRIXFAST8 "X" #define PRIXFAST16 "X" #define PRIXFAST32 "X" #define PRIXFAST64 "lX" /* Macros for printing `intmax_t' and `uintmax_t'. */ #define PRIdMAX "ld" #define PRIiMAX "li" #define PRIoMAX "lo" #define PRIuMAX "lu" #define PRIxMAX "lx" #define PRIXMAX "lX" /* Macros for printing `intptr_t' and `uintptr_t'. */ #define PRIdPTR "d" #define PRIiPTR "i" #define PRIoPTR "o" #define PRIuPTR "u" #define PRIxPTR "x" #define PRIXPTR "X" #endif /* _DPUSYSCORE_INTTYPES_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/iso646.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ISO646_H_ #define _DPUSYSCORE_ISO646_H_ /** * @file iso646.h * @brief Alternative spellings for operators not supported by the ISO646 standard character set. */ /** * @def and * @brief Logical AND. */ #define and && /** * @def and_eq * @brief Bitwise AND accumulation. */ #define and_eq &= /** * @def bitand * @brief Bitwise AND. */ #define bitand & /** * @def bitor * @brief Bitwise OR. */ #define bitor | /** * @def compl * @brief Bitwise NOT. */ #define compl ~ /** * @def not * @brief Logical NOT. */ #define not ! /** * @def not_eq * @brief Difference. */ #define not_eq != /** * @def or * @brief Logical OR. */ #define or || /** * @def or_eq * @brief Bitwise OR accumulation. */ #define or_eq |= /** * @def xor * @brief Bitwise XOR. */ #define xor ^ /** * @def xor_eq * @brief Bitwise XOR accumulation. */ #define xor_eq ^= #endif /* _DPUSYSCORE_ISO646_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/limits.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_LIMITS_H_ #define _DPUSYSCORE_LIMITS_H_ #define SCHAR_MAX (0x0000007f) #define SHRT_MAX (0x00007fff) #define INT_MAX (0x7fffffff) #define LONG_MAX (0x7fffffffffffffffl) #define LLONG_MAX (0x7fffffffffffffffl) #define SCHAR_MIN (-SCHAR_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1) #define INT_MIN (-INT_MAX - 1) #define LONG_MIN (-LONG_MAX - 1) #define LLONG_MIN (-LLONG_MAX - 1) #define UCHAR_MAX (SCHAR_MAX * 2 + 1) #define USHRT_MAX (SHRT_MAX * 2 + 1) #define UINT_MAX (INT_MAX * 2U + 1U) #define ULONG_MAX (LONG_MAX * 2UL + 1UL) #define ULLONG_MAX (LLONG_MAX * 2UL + 1UL) #ifdef __CHAR_UNSIGNED__ /* -funsigned-char */ #define CHAR_MIN 0 #define CHAR_MAX UCHAR_MAX #else #define CHAR_MIN SCHAR_MIN #define CHAR_MAX SCHAR_MAX #endif /* The maximum number of bytes in a multi-byte character. */ #define MB_LEN_MAX 16 /* Limits of integral types */ /** * @def CHAR_BIT * @hideinitializer * @brief The number of bits in a char type. */ #define CHAR_BIT (8) /** * @def WORD_BIT * @hideinitializer * @brief The number of bits in a word type. */ #define WORD_BIT (32) /** * @def LONG_BIT * @hideinitializer * @brief The number of bits in a pseudo-long type. */ #define LONG_BIT (32) /* Minimum of signed integral types */ /** * @def INT8_MIN * @hideinitializer * @brief The minimum value for a value of type int8_t. */ #define INT8_MIN (-0x7f - 1) /** * @def INT16_MIN * @hideinitializer * @brief The minimum value for a value of type int16_t. */ #define INT16_MIN (-0x7fff - 1) /** * @def INT32_MIN * @hideinitializer * @brief The minimum value for a value of type int32_t. */ #define INT32_MIN (-0x7fffffff - 1) /** * @def INT64_MIN * @hideinitializer * @brief The minimum value for a value of type int64_t. */ #define INT64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of signed integral types */ /** * @def INT8_MAX * @hideinitializer * @brief The maximum value for a value of type int8_t. */ #define INT8_MAX (0x7f) /** * @def INT16_MAX * @hideinitializer * @brief The maximum value for a value of type int16_t. */ #define INT16_MAX (0x7fff) /** * @def INT32_MAX * @hideinitializer * @brief The maximum value for a value of type int32_t. */ #define INT32_MAX (0x7fffffff) /** * @def INT64_MAX * @hideinitializer * @brief The maximum value for a value of type int64_t. */ #define INT64_MAX (0x7fffffffffffffffL) /* Maximum of unsigned integral types */ /** * @def UINT8_MAX * @hideinitializer * @brief The maximum value for a value of type uint8_t. */ #define UINT8_MAX (0xff) /** * @def UINT16_MAX * @hideinitializer * @brief The maximum value for a value of type uint16_t. */ #define UINT16_MAX (0xffff) /** * @def UINT32_MAX * @hideinitializer * @brief The maximum value for a value of type uint32_t. */ #define UINT32_MAX (0xffffffff) /** * @def UINT64_MAX * @hideinitializer * @brief The maximum value for a value of type uint64_t. */ #define UINT64_MAX (0xffffffffffffffffUL) /* Minimum of signed integral types having a minimum size */ /** * @def INT_LEAST8_MIN * @hideinitializer * @brief The minimum value for a value of type int_least8_t. */ #define INT_LEAST8_MIN (-0x7f - 1) /** * @def INT_LEAST16_MIN * @hideinitializer * @brief The minimum value for a value of type int_least16_t. */ #define INT_LEAST16_MIN (-0x7fff - 1) /** * @def INT_LEAST32_MIN * @hideinitializer * @brief The minimum value for a value of type int_least32_t. */ #define INT_LEAST32_MIN (-0x7fffffff - 1) /** * @def INT_LEAST64_MIN * @hideinitializer * @brief The minimum value for a value of type int_least64_t. */ #define INT_LEAST64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of signed integral types having a minimum size */ /** * @def INT_LEAST8_MAX * @hideinitializer * @brief The maximum value for a value of type int_least8_t. */ #define INT_LEAST8_MAX (0x7f) /** * @def INT_LEAST16_MAX * @hideinitializer * @brief The maximum value for a value of type int_least16_t. */ #define INT_LEAST16_MAX (0x7fff) /** * @def INT_LEAST32_MAX * @hideinitializer * @brief The maximum value for a value of type int_least32_t. */ #define INT_LEAST32_MAX (0x7fffffff) /** * @def INT_LEAST64_MAX * @hideinitializer * @brief The maximum value for a value of type int_least64_t. */ #define INT_LEAST64_MAX (0x7fffffffffffffffL) /* Maximum of unsigned integral types having a minimum size */ /** * @def UINT_LEAST8_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least8_t. */ #define UINT_LEAST8_MAX (0xff) /** * @def UINT_LEAST16_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least16_t. */ #define UINT_LEAST16_MAX (0xffff) /** * @def UINT_LEAST32_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least32_t. */ #define UINT_LEAST32_MAX (0xffffffff) /** * @def UINT_LEAST64_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least64_t. */ #define UINT_LEAST64_MAX (0xffffffffffffffffUL) /* Minimum of fast signed integral types having a minimum size */ /** * @def INT_FAST8_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast8_t. */ #define INT_FAST8_MIN (-0x7f - 1) /** * @def INT_FAST16_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast16_t. */ #define INT_FAST16_MIN (-0x7fffffff - 1) /** * @def INT_FAST32_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast32_t. */ #define INT_FAST32_MIN (-0x7fffffff - 1) /** * @def INT_FAST64_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast64_t. */ #define INT_FAST64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of fast signed integral types having a minimum size */ /** * @def INT_FAST8_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast8_t. */ #define INT_FAST8_MAX (0x7f) /** * @def INT_FAST16_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast16_t. */ #define INT_FAST16_MAX (0x7fffffff) /** * @def INT_FAST32_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast32_t. */ #define INT_FAST32_MAX (0x7fffffff) /** * @def INT_FAST64_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast64_t. */ #define INT_FAST64_MAX (0x7fffffffffffffffL) /* Maximum of fast unsigned integral types having a minimum size */ /** * @def UINT_FAST8_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast8_t. */ #define UINT_FAST8_MAX (0xff) /** * @def UINT_FAST16_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast16_t. */ #define UINT_FAST16_MAX (0xffffffffU) /** * @def UINT_FAST32_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast32_t. */ #define UINT_FAST32_MAX (0xffffffffU) /** * @def UINT_FAST64_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast64_t. */ #define UINT_FAST64_MAX (0xffffffffffffffffUL) /* Limits for integral types holding void* pointers */ /** * @def INTPTR_MIN * @hideinitializer * @brief The minimum value for a value of type intptr_t. */ #define INTPTR_MIN (-0x7fffffff - 1) /** * @def INTPTR_MAX * @hideinitializer * @brief The maximum value for a value of type intptr_t. */ #define INTPTR_MAX (0x7fffffff) /** * @def UINTPTR_MAX * @hideinitializer * @brief The maximum value for a value of type uintptr_t. */ #define UINTPTR_MAX (0xffffffffU) /* Limits of greatest-width integer types */ /** * @def INTMAX_MIN * @hideinitializer * @brief The minimum value for a value of type intmax_t. */ #define INTMAX_MIN (-0x7fffffffffffffffLL - 1) /** * @def INTMAX_MAX * @hideinitializer * @brief The maximum value for a value of type intmax_t. */ #define INTMAX_MAX (0x7fffffffffffffffLL) /** * @def UINTMAX_MAX * @hideinitializer * @brief The maximum value for a value of type uintmax_t. */ #define UINTMAX_MAX (0xffffffffffffffffULL) /* Limits of others integer types */ /** * @def PTRDIFF_MIN * @hideinitializer * @brief The minimum value for a value of type ptrdiff_t. * @see ptrdiff_t */ #define PTRDIFF_MIN (-0x7fffffff - 1) /** * @def PTRDIFF_MAX * @hideinitializer * @brief The maximum value for a value of type ptrdiff_t. * @see ptrdiff_t */ #define PTRDIFF_MAX (0x7fffffff) /** * @def SIZE_MAX * @hideinitializer * @brief The maximum value for a value of type size_t. * @see size_t */ #define SIZE_MAX (0xffffffffU) /** * @def WCHAR_MIN * @hideinitializer * @brief The minimum value for a value of type wchar_t. * @see wchar_t */ #define WCHAR_MIN (-0x7fffffff - 1) /** * @def WCHAR_MAX * @hideinitializer * @brief The maximum value for a value of type wchar_t. * @see wchar_t */ #define WCHAR_MAX (0x7fffffff) /** * @def WINT_MIN * @hideinitializer * @brief The minimum value for a value of type wint_t. */ #define WINT_MIN (0u) /** * @def WINT_MAX * @hideinitializer * @brief The maximum value for a value of type wint_t. */ #define WINT_MAX (0xffffffffu) /* Macros for integer constant expressions */ /* Signed */ /** * @def INT8_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least8_t */ #define INT8_C(value) value /** * @def INT16_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least16_t */ #define INT16_C(value) value /** * @def INT32_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least32_t */ #define INT32_C(value) value /** * @def INT64_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least64_t */ #define INT64_C(value) value##LL /* Unsigned */ /** * @def UINT8_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least8_t */ #define UINT8_C(value) value##U /** * @def UINT16_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least16_t */ #define UINT16_C(value) value##U /** * @def UINT32_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least32_t */ #define UINT32_C(value) value##U /** * @def UINT64_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least64_t */ #define UINT64_C(value) value##ULL /* Maximum types */ /** * @def INTMAX_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type intmax_t */ #define INTMAX_C(value) value##LL /** * @def UINTMAX_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uintmax_t */ #define UINTMAX_C(value) value##ULL #endif /* _DPUSYSCORE_LIMITS_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/memchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void * memchr(const void *area, int character, size_t size) { const char *ptr = (const char *)area; for (size_t each_byte = 0; each_byte < size; ++each_byte) { if (ptr[each_byte] == character) { return (void *)(ptr + each_byte); } } return NULL; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/memcmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int memcmp(const void *area1, const void *area2, size_t size) { const unsigned char *ptr1 = (const unsigned char *)area1; const unsigned char *ptr2 = (const unsigned char *)area2; for (size_t each_byte = 0; each_byte < size; ++each_byte) { int diff = ptr1[each_byte] - ptr2[each_byte]; if (diff != 0) { return diff; } } return 0; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/memcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include __attribute__((used)) void * __memcpy_wram_4align(void *dest, const void *src, size_t len) { uint32_t *dw = (uint32_t *)dest; uint32_t *sw = (uint32_t *)src; for (uint32_t i = 0; i < (len / sizeof(uint32_t)); ++i) { dw[i] = sw[i]; } return dest; } void * memcpy(void *dest, const void *src, size_t len) { uint8_t *d = (uint8_t *)dest; const uint8_t *s = (const uint8_t *)src; uint32_t *dw; const uint32_t *sw; uint8_t *head; uint8_t *const tail = (uint8_t *)dest + len; /* Set 'body' to the last word boundary */ uint32_t *const body = (uint32_t *)((uintptr_t)tail & ~3); if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { /* Misaligned. no body, no tail. */ head = tail; } else { /* Aligned */ if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) /* len is shorter than the first word boundary */ head = tail; else /* Set 'head' to the first word boundary */ head = (uint8_t *)(((uintptr_t)d + 3) & ~3); } /* Copy head */ uint32_t head_len = head - d; if (head_len != 0) { for (uint32_t i = 0; i < head_len; ++i) d[i] = s[i]; } /* Copy body */ dw = (uint32_t *)(d + head_len); sw = (uint32_t *)(s + head_len); uint32_t body_len = (body < dw) ? 0 : body - dw; if (body_len != 0) { __memcpy_wram_4align(dw, sw, body_len * sizeof(uint32_t)); } /* Copy tail */ d = (uint8_t *)(dw + body_len); s = (const uint8_t *)(sw + body_len); uint32_t tail_len = tail - d; if (tail_len != 0) { for (uint32_t i = 0; i < tail_len; ++i) d[i] = s[i]; } return dest; } __attribute__((used)) __mram_ptr void * __memcpy_mw(__mram_ptr void *dest, const void *src, size_t len) { uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *destCache = (void *)destCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; uint32_t idx = 0; if (destOff != 0) { size_t part = MIN(remaining, MRAM_CACHE_SIZE - destOff); mram_read(dest, destCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, src, part); mram_write(destCache, dest, MRAM_CACHE_SIZE); remaining -= part; idx += part; } if (srcOff == destOff) { while (remaining >= MRAM_CACHE_SIZE) { mram_write(src + idx, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } else { while (remaining >= MRAM_CACHE_SIZE) { memcpy(destCache, src + idx, MRAM_CACHE_SIZE); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } if (remaining != 0) { mram_read(dest + idx, destCache, MRAM_CACHE_SIZE); memcpy(destCache, src + idx, remaining); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); } return dest; } __attribute__((used)) void * __memcpy_wm(void *dest, const __mram_ptr void *src, size_t len) { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; uint32_t idx = 0; size_t part = MIN(remaining, MRAM_CACHE_SIZE - srcOff); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(dest, srcCache + srcOff, part); remaining -= part; idx += part; if (srcOff == destOff) { while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } else { while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(dest + idx, srcCache, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } if (remaining != 0) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(dest + idx, srcCache, remaining); } return dest; } __attribute__((used)) __mram_ptr void * __memcpy_mm(__mram_ptr void *dest, const __mram_ptr void *src, size_t len) { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; void *destCache = (void *)destCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; if (srcOff == destOff) { uint32_t idx = 0; if (destOff != 0) { size_t part = MIN(remaining, MRAM_CACHE_SIZE - srcOff); mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, srcCache + srcOff, part); mram_write(destCache, dest, MRAM_CACHE_SIZE); remaining -= part; idx += part; } while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); mram_write(srcCache, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dest + idx, destCache, MRAM_CACHE_SIZE); mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache, srcCache, remaining); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); } } else { uint32_t srcIdx = 0; uint32_t destIdx = 0; size_t initLen = MIN(remaining, MRAM_CACHE_SIZE - MIN(destOff, srcOff)); if (initLen == remaining) { mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, srcCache + srcOff, remaining); mram_write(destCache, dest, MRAM_CACHE_SIZE); return dest; } mram_read(src, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; if (destOff != 0) { mram_read(dest, destCache, DMA_ALIGNED(destOff)); if (destOff > srcOff) { size_t part = MRAM_CACHE_SIZE - destOff; memcpy(destCache + destOff, srcCache + srcOff, part); srcOff += part; } else { size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache + destOff, srcCache + srcOff, part); mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; size_t part2 = srcOff - destOff; memcpy(destCache + destOff + part, srcCache, part2); srcOff = part2; } mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); destIdx += MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE - destOff; } while (remaining >= MRAM_CACHE_SIZE) { size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache, srcCache + srcOff, part); mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; size_t part2 = srcOff; memcpy(destCache + part, srcCache, part2); mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; destIdx += MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dest + destIdx, destCache, MRAM_CACHE_SIZE); size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache, srcCache + srcOff, part); if (remaining > part) { size_t part2 = remaining - part; mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + part, srcCache, part2); } mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); } } return dest; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/memmove.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include void * memmove(void *dest, const void *src, size_t len) { if ((uintptr_t)dest <= (uintptr_t)src || (uintptr_t)dest >= (uintptr_t)src + len) { /* Start of destination doesn't overlap source, so just use * memcpy(). */ return memcpy(dest, src, len); } else { /* Need to copy from tail because there is overlap. */ char *d = (char *)dest + len; const char *s = (const char *)src + len; uint32_t *dw; const uint32_t *sw; char *head; char *const tail = (char *)dest; /* Set 'body' to the last word boundary */ uint32_t *const body = (uint32_t *)(((uintptr_t)tail + 3) & ~3); if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { /* Misaligned. no body, no tail. */ head = tail; } else { /* Aligned */ if ((uintptr_t)tail > ((uintptr_t)d & ~3)) /* Shorter than the first word boundary */ head = tail; else /* Set 'head' to the first word boundary */ head = (char *)((uintptr_t)d & ~3); } /* Copy head */ uint32_t head_len = d - head; for (int32_t i = head_len - 1; i >= 0; --i) d[i - head_len] = s[i - head_len]; /* Copy body */ dw = (uint32_t *)(d - head_len); sw = (uint32_t *)(s - head_len); uint32_t body_len = (dw < body) ? 0 : dw - body; for (int32_t i = body_len - 1; i >= 0; --i) dw[i - body_len] = sw[i - body_len]; /* Copy tail */ d = (char *)(dw - body_len); s = (const char *)(sw - body_len); uint32_t tail_len = d - tail; for (int32_t i = tail_len - 1; i >= 0; --i) d[i - tail_len] = s[i - tail_len]; return dest; } } __mram_ptr void * __memmove_mm(__mram_ptr void *dest, __mram_ptr const void *src, size_t len) { if ((uintptr_t)dest <= (uintptr_t)src || (uintptr_t)dest >= (uintptr_t)src + len) { /* Start of destination doesn't overlap source, so just use * memcpy(). */ return (__mram_ptr void *)memcpy(dest, src, len); } else { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; void *destCache = (void *)destCache64; __mram_ptr const void *srcIdx = src + len; __mram_ptr void *dstIdx = dest + len; uint32_t remaining = len; uint32_t srcOff = ((uintptr_t)srcIdx) & DMA_OFF_MASK; uint32_t dstOff = ((uintptr_t)dstIdx) & DMA_OFF_MASK; if (srcOff == dstOff) { size_t part = MIN(remaining, srcOff); uint32_t off = srcOff - part; if (dstOff != 0) { srcIdx -= srcOff; dstIdx -= dstOff; mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + off, srcCache + off, part); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); remaining -= part; } srcIdx -= MRAM_CACHE_SIZE; dstIdx -= MRAM_CACHE_SIZE; while (remaining >= MRAM_CACHE_SIZE) { mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); mram_write(srcCache, dstIdx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; srcIdx -= MRAM_CACHE_SIZE; dstIdx -= MRAM_CACHE_SIZE; } if (remaining != 0) { uint32_t off = MRAM_CACHE_SIZE - remaining; mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + off, srcCache + off, remaining); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); } } else { size_t initLen = MIN(remaining, MIN(dstOff, srcOff)); if (initLen == remaining) { mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + dstOff - remaining, srcCache + srcOff - remaining, remaining); mram_write(destCache, dest, MRAM_CACHE_SIZE); return dest; } mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; if (dstOff != 0) { size_t part = DMA_ALIGNED(dstOff); mram_read(dstIdx, destCache + MRAM_CACHE_SIZE - part, part); if (srcOff > dstOff) { part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - dstOff); memcpy(destCache, srcCache + srcOff - part, part); srcOff -= part; } else { part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + dstOff - part, srcCache, part); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; size_t part2 = dstOff - part; memcpy(destCache, srcCache + MRAM_CACHE_SIZE - part2, part2); srcOff = MRAM_CACHE_SIZE - part2; } mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); dstIdx -= MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE - (DMA_ALIGNMENT - dstOff); } while (remaining >= MRAM_CACHE_SIZE) { size_t part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + MRAM_CACHE_SIZE - part, srcCache, part); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; size_t part2 = MRAM_CACHE_SIZE - part; memcpy(destCache, srcCache + MRAM_CACHE_SIZE - part2, part2); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); dstIdx -= MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); size_t part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + MRAM_CACHE_SIZE - part, srcCache, part); if (remaining > part) { size_t part2 = remaining - part; mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + MRAM_CACHE_SIZE - remaining, srcCache + MRAM_CACHE_SIZE - part2, part2); } mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); } } return dest; } } ================================================ FILE: golang/uPIMulator/sdk/stdlib/memmram_utils.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_MEMMRAM_UTILS_H_ #define _DPUSYSCORE_MEMMRAM_UTILS_H_ #define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define ALIGN(x, a) ALIGN_MASK((x), (a)-1) #define DMA_ALIGNMENT 8 #define DMA_OFF_MASK (DMA_ALIGNMENT - 1) #define DMA_ALIGNED(x) ALIGN(x, DMA_ALIGNMENT) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MRAM_CACHE_SIZE 8 #endif /* _DPUSYSCORE_MEMMRAM_UTILS_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/memset.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include static void * __memset_wram_1align(void *dest, int c, size_t len) { uint8_t *dest8 = (uint8_t *)(dest); for (uint32_t i = 0; i < (len); ++i) { dest8[i] = (c); } return dest; } typedef uint32_t memset_wram_t; /* Requisite: * - dest: align on 4 bytes * - len: mutiple of 4 bytes */ void *__attribute__((used)) __memset_wram_4align(void *dest, int c, size_t len) { uint32_t cccc; memset_wram_t *dest32 = (memset_wram_t *)dest; c &= 0xff; /* Clear upper bits before ORing below */ cccc = c | (c << 8) | (c << 16) | (c << 24); for (uint32_t i = 0; i < len / sizeof(memset_wram_t); ++i) { dest32[i] = cccc; } return dest; } void * memset(void *dest, int c, size_t len) { const uint32_t align = sizeof(memset_wram_t); const uint32_t align_off_mask = (align - 1); uint32_t align_offset = ((uintptr_t)dest) & align_off_mask; uint8_t *d = (uint8_t *)dest; /* memset head */ if (align_offset != 0) { size_t head_len = align - align_offset; if (head_len > len) { head_len = len; } __memset_wram_1align(d, c, head_len); len -= head_len; d += head_len; } /* memset body */ if (len >= align) { size_t body_len = len & (~align_off_mask); __memset_wram_4align(d, c, body_len); len -= body_len; d += body_len; } /* memset tail */ if (len > 0) { __memset_wram_1align(d, c, len); } return dest; } #define MEMSET_MRAM_CACHE_SIZE (8) /* Requisite: * - dest: align on 8 bytes * - len: mutiple of 8 bytes */ __attribute__((used)) __mram_ptr void * __memset_mram_8align(__mram_ptr void *dest, int c, size_t len) { __dma_aligned uint8_t cache64[MEMSET_MRAM_CACHE_SIZE]; void *cache = (void *)cache64; __memset_wram_4align(cache, c, MEMSET_MRAM_CACHE_SIZE); for (uint32_t idx = 0; idx < len; idx += MEMSET_MRAM_CACHE_SIZE) { mram_write(cache, dest + idx, MEMSET_MRAM_CACHE_SIZE); } return dest; } __attribute__((used)) __mram_ptr void * __memset_mram(__mram_ptr void *dest, int c, size_t len) { __dma_aligned uint8_t cache64[MEMSET_MRAM_CACHE_SIZE]; void *cache = (void *)cache64; __mram_ptr uint8_t *d = (__mram_ptr uint8_t *)((uintptr_t)dest & (~DMA_OFF_MASK)); uint32_t align_offset = ((uintptr_t)dest) & DMA_OFF_MASK; /* memset head */ if (align_offset != 0) { size_t head_len = MEMSET_MRAM_CACHE_SIZE - align_offset; if (head_len > len) { head_len = len; } mram_read(d, cache, MEMSET_MRAM_CACHE_SIZE); __memset_wram_1align(cache + align_offset, c, head_len); mram_write(cache, d, MEMSET_MRAM_CACHE_SIZE); len -= head_len; d += MEMSET_MRAM_CACHE_SIZE; } /* memset body */ if (len >= MRAM_CACHE_SIZE) { size_t body_len = len & (~(MEMSET_MRAM_CACHE_SIZE - 1)); __memset_mram_8align(d, c, body_len); len -= body_len; d += body_len; } /* memset tail */ if (len > 0) { mram_read(d, cache, MEMSET_MRAM_CACHE_SIZE); __memset_wram_1align(cache, c, len); mram_write(cache, d, MEMSET_MRAM_CACHE_SIZE); } return dest; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdalign.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDALIGN_H_ #define _DPUSYSCORE_STDALIGN_H_ /** * @file stdalign.h * @brief Defines align macros. */ /** * @def alignas * @brief _Alignas specifier. */ #define alignas _Alignas /** * @def alignof * @brief _Alignof operator. */ #define alignof _Alignof /** * @def __alignas_is_defined * @brief Whether the alignas macro is defined. */ #define __alignas_is_defined 1 /** * @def __alignof_is_defined * @brief Whether the alignof macro is defined. */ #define __alignof_is_defined 1 #endif /* _DPUSYSCORE_STDALIGN_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdarg.h ================================================ /*===---- stdarg.h - Variable argument handling ----------------------------=== * * Copyright (c) 2008 Eli Friedman * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * *===-----------------------------------------------------------------------=== */ #ifndef __STDARG_H #define __STDARG_H #ifndef _VA_LIST typedef __builtin_va_list va_list; #define _VA_LIST #endif #define va_start(ap, param) __builtin_va_start(ap, param) #define va_end(ap) __builtin_va_end(ap) #define va_arg(ap, type) __builtin_va_arg(ap, type) /* GCC always defines __va_copy, but does not define va_copy unless in c99 mode * or -ansi is not specified, since it was not part of C90. */ #define __va_copy(d, s) __builtin_va_copy(d, s) #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__) #define va_copy(dest, src) __builtin_va_copy(dest, src) #endif #ifndef __GNUC_VA_LIST #define __GNUC_VA_LIST 1 typedef __builtin_va_list __gnuc_va_list; #endif #endif /* __STDARG_H */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdbool.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDBOOL_H_ #define _DPUSYSCORE_STDBOOL_H_ /** * @file stdbool.h * @brief Defines the boolean type. */ /** * @def __bool_true_false_are_defined * @brief Whether the boolean type and values are defined. */ #define __bool_true_false_are_defined 1 /** * @def bool * @brief The boolean type. */ #define bool _Bool /** * @def true * @brief The true constant, represented by 1 */ #define true 1 /** * @def false * @brief The false constant, represented by 0 */ #define false 0 #endif /* _DPUSYSCORE_STDBOOL_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stddef.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDDEF_H_ #define _DPUSYSCORE_STDDEF_H_ /** * @file stddef.h * @brief Defines some standard types. */ /** * @brief The type for the result of subtracting two pointers. */ typedef int ptrdiff_t; /** * @brief The type for the result of the sizeof operator. * * @internal No memory or object in the DPU can be more than megabytes of data. * As a consequence, we can restrict the sizes to 32 bits, which is * already a lot. */ typedef unsigned int size_t; /** * @brief Value whose alignment requirement is at least as strict (as large) as that of every scalar type. */ typedef unsigned long int max_align_t; /** * @brief The type for wide-character codes. */ typedef unsigned int wchar_t; /** * @def NULL * @brief The null pointer constant. */ #define NULL ((void *)0) /** * @def offsetof * @hideinitializer * @brief Offset in bytes to the structure member, from the beginning of its structure. * * @param st the structure * @param m the member name * * @internal Raw version of offsetof, should be enough in our context, with all the underlying risks. */ #define offsetof(st, m) ((size_t)(&((st *)0)->m)) #endif /* _DPUSYSCORE_STDDEF_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdint.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDINT_H_ #define _DPUSYSCORE_STDINT_H_ /** * @file stdint.h * @brief Provides abstraction over machine types. */ /* Exact integer types */ /* Signed */ /** * @brief A signed 8-bit value. */ typedef signed char int8_t; /** * @brief A signed 16-bit value. */ typedef short int int16_t; /** * @brief A signed 32-bit value. */ typedef int int32_t; /** * @brief A signed 64-bit value. */ typedef long long int int64_t; /* Unsigned */ /** * @brief An unsigned 8-bit value. */ typedef unsigned char uint8_t; /** * @brief An unsigned 16-bit value. */ typedef unsigned short int uint16_t; /** * @brief An unsigned 32-bit value. */ typedef unsigned int uint32_t; /** * @brief An unsigned 64-bit value. */ typedef unsigned long int uint64_t; /* Small types */ /* Signed */ /** * @brief A signed value on at least 8 bits. */ typedef signed char int_least8_t; /** * @brief A signed value on at least 16 bits. */ typedef short int int_least16_t; /** * @brief A signed value on at least 32 bits. */ typedef int int_least32_t; /** * @brief A signed value on at least 64 bits. */ typedef long int int_least64_t; /* Unsigned */ /** * @brief An unsigned value on at least 8 bits. */ typedef unsigned char uint_least8_t; /** * @brief An unsigned value on at least 16 bits. */ typedef unsigned short int uint_least16_t; /** * @brief An unsigned value on at least 32 bits. */ typedef unsigned int uint_least32_t; /** * @brief An unsigned value on at least 64 bits. */ typedef unsigned long int uint_least64_t; /* Fast types */ /* Signed */ /** * @brief A signed value on at least 8 bits, optimized for that length. */ typedef signed char int_fast8_t; /** * @brief A signed value on at least 16 bits, optimized for that length. */ typedef int int_fast16_t; /** * @brief A signed value on at least 32 bits, optimized for that length. */ typedef int int_fast32_t; /** * @brief A signed value on at least 64 bits, optimized for that length. */ typedef long int int_fast64_t; /* Unsigned */ /** * @brief An unsigned value on at least 8 bits, optimized for that length. */ typedef unsigned char uint_fast8_t; /** * @brief An unsigned value on at least 16 bits, optimized for that length. */ typedef unsigned int uint_fast16_t; /** * @brief An unsigned value on at least 32 bits, optimized for that length. */ typedef unsigned int uint_fast32_t; /** * @brief An unsigned value on at least 64 bits, optimized for that length. */ typedef unsigned long int uint_fast64_t; /* Types for void* pointers */ /** * @brief A signed value which can contain a pointer value. */ typedef int intptr_t; /** * @brief An unsigned value which can contain a pointer value. */ typedef unsigned int uintptr_t; /* Greatest-width integer types */ /** * @brief A signed value which can contain all signed values. */ typedef long long int intmax_t; /** * @brief An unsigned value which can contain all unsigned values. */ typedef unsigned long long int uintmax_t; #include #endif /* _DPUSYSCORE_STDINT_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdio.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #include #include #define DEFAULT_STDOUT_BUFFER_SIZE (1 << 20) unsigned char __weak __mram_noinit __stdout_buffer[DEFAULT_STDOUT_BUFFER_SIZE]; unsigned int __weak __stdout_buffer_size = DEFAULT_STDOUT_BUFFER_SIZE; /* __lower_data: needed to make sure that the structure address will be less that a signed12 * (sd endian:e ra off:s12 imm:s16 used in bootstrap). * * __dma_aligned: needed to make sure that the structure address will be aligned on 8 bytes (for sd in bootstrap as well). * * This structure is initialize at zero in the bootsrap */ __lower_data(__STR(__STDOUT_BUFFER_STATE)) __dma_aligned struct { uint32_t wp; uint32_t has_wrapped; } __STDOUT_BUFFER_STATE; static uint32_t __stdout_buffer_write_pointer_initial; static uint32_t __stdout_nr_of_wrapping; #define STDOUT_CACHE_BUFFER_SIZE 8 _Static_assert((STDOUT_CACHE_BUFFER_SIZE >= 8) && (STDOUT_CACHE_BUFFER_SIZE <= 2048) && (STDOUT_CACHE_BUFFER_SIZE % 8 == 0), "STDOUT_CACHE_BUFFER_SIZE needs to be a multiple of 8 in ]0; 2048]"); static char __stdout_cache_buffer[STDOUT_CACHE_BUFFER_SIZE] __dma_aligned; static unsigned int __stdout_cache_write_index; ATOMIC_BIT_INIT(__stdout_buffer_lock); __attribute__((noinline)) static void __transfer_cache_to_mram() { __mram_ptr void *offset_in_mram = (__mram_ptr void *)(__STDOUT_BUFFER_STATE.wp + (uintptr_t)__stdout_buffer); __STDOUT_BUFFER_STATE.wp += STDOUT_CACHE_BUFFER_SIZE; if (__STDOUT_BUFFER_STATE.wp >= __stdout_buffer_size) { __STDOUT_BUFFER_STATE.wp = 0; __STDOUT_BUFFER_STATE.has_wrapped = true; __stdout_nr_of_wrapping++; } mram_write(__stdout_cache_buffer, offset_in_mram, STDOUT_CACHE_BUFFER_SIZE); } // Generic template that will be used everywhere: cache a byte and flush to MRAM // when the cache is full. __attribute__((noinline)) static void __write_byte_and_flush_if_needed(uint8_t byte) { __stdout_cache_buffer[__stdout_cache_write_index++] = byte; if (__stdout_cache_write_index == STDOUT_CACHE_BUFFER_SIZE) { __transfer_cache_to_mram(); __stdout_cache_write_index = 0; } } __attribute__((noinline)) static void __finalized_print_sequence() { memset(__stdout_cache_buffer + __stdout_cache_write_index, 0, STDOUT_CACHE_BUFFER_SIZE - __stdout_cache_write_index); __transfer_cache_to_mram(); if (__stdout_nr_of_wrapping > 1 || (__stdout_nr_of_wrapping == 1 && __STDOUT_BUFFER_STATE.wp > __stdout_buffer_write_pointer_initial)) __asm__("fault " __STR(__FAULT_PRINTF_OVERFLOW__)); // need to throw fault because we will not be able to print the buffer } __attribute__((noinline)) static void __open_print_sequence() { ATOMIC_BIT_ACQUIRE(__stdout_buffer_lock); __stdout_cache_write_index = 0; __stdout_nr_of_wrapping = 0; __stdout_buffer_write_pointer_initial = __STDOUT_BUFFER_STATE.wp; } /* Nothing else that the release instruction should be in this function in order to make sure that the print routine in complete * at this point*/ __attribute__((noinline)) static void __close_print_sequence() { ATOMIC_BIT_RELEASE(__stdout_buffer_lock); } void printf(const char *restrict format, ...) { bool insert_string_arg = true; bool insert_string_arg_end_character = false; char *current_format_char_ptr = (char *)format; __open_print_sequence(); va_list args; va_start(args, format); for (; *current_format_char_ptr != '\0'; ++current_format_char_ptr) { if (*current_format_char_ptr == '%') { ++current_format_char_ptr; if (*current_format_char_ptr == '\0') break; if (*current_format_char_ptr == '%') goto standard_character_format_process; __write_byte_and_flush_if_needed('%'); while (*current_format_char_ptr != '\0') { if (*current_format_char_ptr == 'l') { __write_byte_and_flush_if_needed(*current_format_char_ptr); ++current_format_char_ptr; continue; } if ((*current_format_char_ptr == 'L') || (*current_format_char_ptr == 'z')) { ++current_format_char_ptr; continue; } if (*current_format_char_ptr == 'i') { __write_byte_and_flush_if_needed('d'); break; } __write_byte_and_flush_if_needed(*current_format_char_ptr); if (((*current_format_char_ptr >= 'A') && (*current_format_char_ptr <= 'Z')) || ((*current_format_char_ptr >= 'a') && (*current_format_char_ptr <= 'z'))) break; ++current_format_char_ptr; } insert_string_arg = true; } else { standard_character_format_process: if (insert_string_arg) { __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('s'); insert_string_arg = false; } } } __write_byte_and_flush_if_needed('\0'); current_format_char_ptr = (char *)format; for (; *current_format_char_ptr != '\0'; ++current_format_char_ptr) { if (*current_format_char_ptr == '%') { ++current_format_char_ptr; if (*current_format_char_ptr == '\0') break; if (*current_format_char_ptr == '%') goto standard_character_process; if (insert_string_arg_end_character) { insert_string_arg_end_character = false; __write_byte_and_flush_if_needed('\0'); } bool arg_is_64_bits = false; while (*current_format_char_ptr != '\0') { if ((*current_format_char_ptr == 'l') || (*current_format_char_ptr == 'L')) { arg_is_64_bits = true; current_format_char_ptr++; continue; } else if (*current_format_char_ptr == 'z') { current_format_char_ptr++; continue; } if (((*current_format_char_ptr >= 'A') && (*current_format_char_ptr <= 'Z')) || ((*current_format_char_ptr >= 'a') && (*current_format_char_ptr <= 'z'))) break; ++current_format_char_ptr; } switch (*current_format_char_ptr) { case 's': { char *arg = (char *)va_arg(args, int); while (*arg != '\0') { __write_byte_and_flush_if_needed(*arg); arg++; } __write_byte_and_flush_if_needed('\0'); break; } case 'c': { char arg_as_char = (char)va_arg(args, int); __write_byte_and_flush_if_needed(arg_as_char); break; } case 'f': case 'e': case 'E': case 'g': case 'G': { __asm__ volatile("nop"); double val = va_arg(args, double); char *arg = (char *)&val; for (int i = 0; i < 8; i++) { char arg_byte = arg[i]; __write_byte_and_flush_if_needed(arg_byte); } break; } default: { unsigned int arg_size_in_bytes; long val; if (arg_is_64_bits) { val = va_arg(args, long); arg_size_in_bytes = 8; } else { val = (long)va_arg(args, int); arg_size_in_bytes = 4; } char *arg = (char *)&val; for (unsigned int i = 0; i < arg_size_in_bytes; i++) { char arg_byte = arg[i]; __write_byte_and_flush_if_needed(arg_byte); } } } } else { standard_character_process: __write_byte_and_flush_if_needed(*current_format_char_ptr); insert_string_arg_end_character = true; } } if (insert_string_arg_end_character) { __write_byte_and_flush_if_needed('\0'); } va_end(args); __finalized_print_sequence(); __close_print_sequence(); } void puts(const char *str) { __open_print_sequence(); __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('s'); __write_byte_and_flush_if_needed('\0'); for (char *current_char_ptr = (char *)str; *current_char_ptr != '\0'; current_char_ptr++) { __write_byte_and_flush_if_needed(*current_char_ptr); } __write_byte_and_flush_if_needed('\n'); __write_byte_and_flush_if_needed('\0'); __finalized_print_sequence(); __close_print_sequence(); } void putchar(int c) { __open_print_sequence(); __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('c'); __write_byte_and_flush_if_needed('\0'); char arg_as_char = (char)c; __write_byte_and_flush_if_needed(arg_as_char); __finalized_print_sequence(); __close_print_sequence(); } ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdio.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDIO_H_ #define _DPUSYSCORE_STDIO_H_ #include #include /** * @file stdio.h * @brief Standard input/output library functions. */ /** * @def STDOUT_BUFFER_INIT * @hideinitializer * @brief Declares the stdout buffer. Should be used as when declaring a global variable. * @param size the size of the stdout buffer. Must be a multiple of 8, and greater than 0. */ #define STDOUT_BUFFER_INIT(size) \ _Static_assert((size >= 8) && (((size)&7) == 0), "stdout buffer size must be a multiple of 8 and > 0"); \ unsigned char __dma_aligned __mram_noinit __stdout_buffer[(size)]; \ const unsigned int __stdout_buffer_size = (size); /** * @fn printf * @brief Writes the formatted data in the stdout buffer. * * This function has a prototype close to the one of the standard printf function. * However, the format string comply to the java.util.Formatter format, which is * similar to the printf format, but not quit exactly the same. Date formatter may * produce interpreted results, but they will probably be incorrect. Every format * specifier should reference one and only one of the variadic argument (eg. "%n" * is not supported). * * There is no compile-time check to verify that the format is correct: any other * character in the format string will not be interpreted. * * @param format how the logged data should be formatted * @param ... the different data to be printed */ void __attribute__((format(printf, 1, 2))) printf(const char *restrict format, ...); /** * @fn puts * @brief Writes the string in the stdout buffer. A newline character is appended to the output. * @param str the null-terminated string to be written */ void puts(const char *str); /** * @fn putchar * @brief Writes the character in the stdout buffer. * @param c the character to be written */ void putchar(int c); #endif /* _DPUSYSCORE_STDIO_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdlib.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_STDLIB_H #define DPUSYSCORE_STDLIB_H /** * @file stdlib.h * @brief Elementary standard C functions: calls the system function halt. */ #include #include /** * @def EXIT_FAILURE * @hideinitializer * @brief Unsuccessful termination for exit(). */ #define EXIT_FAILURE 1 /** * @def EXIT_SUCCESS * @hideinitializer * @brief Successful termination for exit(). */ #define EXIT_SUCCESS 0 /** * @brief Aborts the DPU execution triggering a processor fault. */ __NO_RETURN void abort(void); /** * @brief Terminates the invoking tasklet, returning the specified status. */ __NO_RETURN void exit(int status); /** * @brief Get an environment variable, or NULL. In the DPU case, always NULL. */ static inline char * getenv(__attribute__((unused)) const char *name) { return NULL; } /** * @brief Returns the absolute value of the argument. */ static inline int abs(int x) { return (x < 0) ? -x : x; } /** * @brief Returns the absolute value of the argument. */ static inline long int labs(long int x) { return (x < 0) ? -x : x; } /** * @brief Returns the absolute value of the argument. */ static inline long long int llabs(long long int x) { return (x < 0) ? -x : x; } typedef struct { int quot; int rem; } div_t; typedef struct { long int quot; long int rem; } ldiv_t; typedef struct { long long int quot; long long int rem; } lldiv_t; static inline div_t div(int numer, int denom) { div_t result = { numer / denom, numer % denom }; return result; } static inline ldiv_t ldiv(long int numer, long int denom) { ldiv_t result = { numer / denom, numer % denom }; return result; } static inline lldiv_t lldiv(long long int numer, long long int denom) { lldiv_t result = { numer / denom, numer % denom }; return result; } /** * @brief Converts a string to an integer * * Function converts the initial part of the string in nptr to an integer value. The string may begin * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. * * Conversion stops at the first character not representing a digit. If an underflow occurs, atoi() * returns INT_MIN. If an overflow occurs, atoi() returns INT_MAX. In both cases errno is set to ERANGE. * * * @param nptr string that contains an integer in a string format * @return the result of conversion unless the value would overflow or underflow. */ int atoi(const char *nptr); /** * @brief Converts a string to a long integer (64 bits) * * Function converts the initial part of the string in nptr to a long value. The string may begin * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. * * Conversion stops at the first character not representing a digit. If an underflow occurs, atol() * returns LONG_MIN. If an overflow occurs, atol() returns LONG_MAX. In both cases errno is set to ERANGE. * * * @param nptr string that contains an integer in a string format * @return the result of conversion unless the value would overflow or underflow. */ long atol(const char *nptr); ///** // * @brief Converts a string to a long integer (64 bits) according to the given base // * between 2 and 36 inclusive, or be the special value 0 // * // * TODO : If the given base is oustide of the range [2...36], then errno is set to EINVAL // * // * Function converts the initial part of the string in nptr to a long value. The string may begin // * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. // * // * If base is zero or 16, the string may then include a "0x" prefix, and the number will be read // * in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', // * in which case it is taken as 8 (octal). // * // * Conversion stops at the first character not representing a digit in the given base. // * Accepted digits are : in bases above 10, the letter 'A' in either uppercase or lowercase // * represents 10, 'B' represents 11, and so forth, with 'Z' representing 35. // * // * If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. // * If there were no digits at all, strtol() stores the original value of nptr in *endptr (and // * returns 0). In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire // * string is valid. // * // * If an underflow occurs, atol() returns LONG_MIN. If an overflow occurs, atol() // * returns LONG_MAX. TODO!!! In both cases errno is set to ERANGE. // * // * @param nptr string that contains an integer in a string format // * @param endptr // * @param base // // * @return the result of conversion unless the value would overflow or underflow. //*/ // long int strtol(const char *nptr, char **endptr, int base); // TODO : strtol() doesn't work : has to be written in assembly #endif /* DPUSYSCORE_STDLIB_H */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stdnoreturn.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDNORETURN_H_ #define _DPUSYSCORE_STDNORETURN_H_ /** * @file stdnoreturn.h * @brief Defines the noreturn macro. */ /** * @def noreturn * @brief _Noreturn attribute. */ #define noreturn _Noreturn #endif /* _DPUSYSCORE_STDNORETURN_H_ */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/stpcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ char * stpcpy(char *destination, const char *source) { char c = *source; while (c != '\0') { *destination = c; destination++; source++; c = *source; } *destination = c; return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/stpncpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * stpncpy(char *destination, const char *source, size_t size) { char c = *source; size_t each_byte; for (each_byte = 0; each_byte < size; ++each_byte) { if (c == '\0') { char *null_char_ptr = destination; for (; each_byte < size; ++each_byte) { *destination = '\0'; destination++; } return null_char_ptr; } *destination = c; destination++; source++; c = *source; } return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strcat.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strcat(char *destination, const char *source) { size_t length = strlen(destination); unsigned int i; for (i = 0; source[i] != '\0'; i++) { destination[length + i] = source[i]; } destination[length + i] = '\0'; return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strchr(const char *string, int character) { char *str = (char *)string; unsigned char c = *str; while (1) { if (c == character) { return str; } if (c == '\0') { return NULL; } str++; c = *str; } } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strcmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int strcmp(const char *string1, const char *string2) { unsigned char c1 = *string1; unsigned char c2 = *string2; while (c1 != '\0') { if (c1 - c2 != 0) { return c1 - c2; } string1++; string2++; c1 = *string1; c2 = *string2; } return c1 - c2; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strcpy(char *destination, const char *source) { char *ptr = destination; char c = *source; while (c != '\0') { *ptr = c; ptr++; source++; c = *source; } *ptr = c; return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strcspn.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include // TODO Possible optimization: // use of the table of indexation that indicates if the character should or should not be accepted/rejected // in this case we will need 128 bits (as there are 128 ascii characters) ( = 16 bytes = 4 words ) per runtime // => 4x24 = 96 words of 32 bits. // // TODO Another solution would be to stock this table only temporarily with the allocation function, but, currently, it's not an // option. size_t strcspn(const char *string, const char *reject) { size_t prefix_length; for (prefix_length = 0; string[prefix_length] != '\0'; ++prefix_length) { char c = string[prefix_length]; for (unsigned int reject_index = 0; reject[reject_index] != '\0'; ++reject_index) { if (reject[reject_index] == c) { return prefix_length; } } } return prefix_length; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strdup.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" #include "buddy_alloc.h" char * strdup(const char *string) { size_t length = strlen(string) + 1; // we get the length of the string for memory allocation char *result = buddy_alloc(length); // we allocate length+1 bytes for the duplicate if (result != NULL) { memcpy(result, string, length); // we copy length bytes from string to the duplicate } return result; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strerror.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include "errno.h" // http://www.delorie.com/gnu/docs/glibc/libc_17.html // static char* strerror_errors[] = { "Success", //"E2BIG", "EACCES", "EADDRINUSE", "EADDRNOTAVAIL", "EAFNOSUPPORT", "EAGAIN", "EALREADY", "EBADF", //"EBADMSG", "EBUSY", "ECANCELED", "ECHILD", "ECONNABORTED", "ECONNREFUSED", "ECONNRESET", "EDEADLK", //"EDESTADDRREQ", "EDOM", "EDQUOT", "EEXIST", "EFAULT", "EFBIG", "EHOSTUNREACH", "EIDRM", //"EILSEQ", "EINPROGRESS", "EINTR", "EINVAL", "EIO", "EISCONN", "EISDIR", "ELOOP", //"EMFILE", "EMLINK", "EMSGSIZE", "EMULTIHOP", "ENAMETOOLONG", "ENETDOWN", "ENETRESET", "ENETUNREACH", //"ENFILE", "ENOBUFS", "ENODATA", "ENODEV", "ENOENT", "ENOEXEC", "ENOLCK", "ENOLINK", //"ENOMEM", "ENOMSG", "ENOPROTOOPT", "ENOSPC", "ENOSR", "ENOSTR", "ENOSYS", "ENOTCONN", //"ENOTDIR", "ENOTEMPTY", "ENOTRECOVERABLE", "ENOTSOCK", "ENOTSUP", "ENOTTY", "ENXIO", "EOPNOTSUPP", //"EOVERFLOW", "EOWNERDEAD", "EPERM", "EPIPE", "EPROTO", "EPROTONOSUPPORT", "EPROTOTYPE", "ERANGE", //"EROFS", "ESPIPE", "ESRCH", "ESTALE", "ETIME", "ETIMEDOUT", "ETXTBSY", "EWOULDBLOCK", //"EXDEV" //}; // 81 errors in total including 2 not supported ones. const static char *strerror_errors_complete[] = { "Success", "Argument list too long", "Permission denied", "Address in use", "Address not available", "Address family not supported", "Resource unavailable, try again", "Connection already in progress", "Bad file descriptor", "Bad message", "Device or resource busy", "Operation canceled", "No child processes", "Connection aborted", "Connection refused", "Connection reset", "Resource deadlock would occur", "Destination address required", "Mathematics argument out of domain of function", "Disk quota exceeded", "File exists", "Bad address", "File too big", "Host unreachable", "Identifier removed", "Illegal byte sequence", "Operation in progress", "Interrupted function", "Invalid argument", "I/O error", "Socket is connected", "File is a directory", "Too many levels of symbolic links", "File descriptor value too large", "Too many links", "Message too large", "EMULTIHOP", "Filename too long", "Network is down", "Connection aborted by network", "Network unreachable", "Too many files open in system", "No buffer space available", "No message is available on the STREAM head read queue", "No such device", "No such file or directory", "Executable file format error", "No locks available", "ENOLINK", "Not enough space", "No message of the desired type", "Protocol unavailable", "No space left on device", "No STREAM resources", "Not a STREAM", "Function not supported", "The socket is not connected", "Not a directory or a symbolic link to a directory", "Directory not empty", "State not recoverable", "Not a socket", "Not supported", "Inappropriate I/O control operation", "No such device or address", "Operation not supported on socket", "Value too large to be stored in data type", "Previous owner died", "Operation not permitted", "Broken pipe", "Protocol error", "Protocol not supported", "Protocol wrong type for socket", "Result too large", "Read-only file system", "Invalid seek", "No such process", "ESTALE", "Stream ioctl() timeout", "Connection timed out", "Text file busy", "Operation would block", "Cross-device link", "Unknown error" }; char * strerror(int errnum) { unsigned int length = sizeof(strerror_errors_complete) / sizeof(strerror_errors_complete[0]) - 1; //-1 for "Unknown error" if (((unsigned int)errnum) >= length) { errno = EINVAL; return (char *)strerror_errors_complete[length]; } return (char *)strerror_errors_complete[errnum]; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/string.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_STRING_H #define DPUSYSCORE_STRING_H /** * @file string.h * @brief Provides functions to manipulate arrays of characters. */ #include /** * @brief Computes the length of the given null-terminated string. * * @param string the string for which we want the length. * @return The length of the string, not including the null character. */ size_t strlen(const char *string); /** * @brief Computes the length of the given null-terminated string if this length is less than max_len. * strnlen checks at most max_len bytes and returns max_len if it has read as many bytes. * * @param string the string for which we want to find the length. * @param max_len maximum number of bytes to check * @return The length of the string, not including the null character or max_len if null character * wasn't found. */ size_t strnlen(const char *string, size_t max_len); /** * @brief Compares the first size bytes of area1 and area2. * * @param area1 the pointer to the start of the first area of the comparison * @param area2 the pointer to the start of the second area of the comparison * @param size the number of bytes to compare between each area. * @return 0 if the areas are the same, a non-zero value otherwise. */ int memcmp(const void *area1, const void *area2, size_t size); /** * @brief Compares the two null-terminated strings string1 and string2. * * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @return 0 if the strings are the same, a non-zero value otherwise. */ int strcmp(const char *string1, const char *string2); /** * @brief Compares the first size bytes of the two null-terminated strings string1 and * string2. * * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @param size the maximum number of bytes to compare between each string. * @return 0 if the strings are the same, a non-zero value otherwise. */ int strncmp(const char *string1, const char *string2, size_t size); /** * @brief Set the first size bytes of area at value. * * @param area the pointer to the start of the area to set * @param value the value at which the area is set * @param size the number of bytes being set * @return A pointer to the start of the set area. */ void * memset(void *area, int value, size_t size); /** * @brief Search for the first occurrence of character in the first size bytes of area. * * @param area the pointer to the start of the area to search * @param character the value to search for * @param size the number of bytes to search * @return A pointer to the first occurrence, if it exists, NULL otherwise. */ void * memchr(const void *area, int character, size_t size); /** * @brief Concatenate the string source after the string destination. * * @param destination the pointer to the start of the first string * @param source the pointer to the start of the second string * @return A pointer to the start of the concatenated string. */ char * strcat(char *destination, const char *source); /** * @brief Concatenate the first size bytes of the string source after the string * destination. * * @param destination the pointer to the start of the first string * @param source the pointer to the start of the second string * @param size the maximum number of bytes to concatenate * @return A pointer to the start of the concatenated string. */ char * strncat(char *destination, const char *source, size_t size); /** * @brief Search for the first occurrence of character in the string. * * @param string the pointer to the start of the string to search * @param character the value to search for * @return A pointer to the first occurrence, if it exists, NULL otherwise. */ char * strchr(const char *string, int character); /** * @brief Search for the last occurrence of character in the string. * * @param string the pointer to the start of the string to search * @param character the value to search for * @return A pointer to the last occurrence, if it exists, NULL otherwise. */ char * strrchr(const char *string, int character); /** * @brief Copy size bytes from source into destination. * * @warning This function is not safe for overlapping memory blocks. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the area to copy * @param size the number of bytes to copy * @return A pointer to the start of the copied area. */ void * memcpy(void *destination, const void *source, size_t size); /** * @brief Copy size bytes from source into destination. * * This is a safer method than memcpy for overlapping memory blocks. * * @see memcpy * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the area to copy * @param size the number of bytes to copy * @return A pointer to the start of the copied area. */ void * memmove(void *destination, const void *source, size_t size); /** * @brief Copy the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @return A pointer to the start of the copied string. */ char * strcpy(char *destination, const char *source); /** * @brief Copy size bytes from the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the start of the copied string. */ char * strncpy(char *destination, const char *source, size_t size); /** * @def strxfrm * @hideinitializer * @brief Transform the first size bytes of the string source into current locale and place them in the * string destination. * * There is no concept of "locale" in the DPU, implying that the related functions behave as native, "locale-less", functions. * This function is just a synonym of strncpy. * * @warning This function is not safe for overlapping strings. * * @see strncpy * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the start of the copied string. */ #define strxfrm strncpy /** * @def strcoll * @hideinitializer * @brief Compare two null-terminated strings using the current locale. * * There is no concept of "locale" in the DPU, implying that the related functions behave as native, "locale-less", functions. * This function is just a synonym of strcmp. * * @see strcmp * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @return 0 if the strings are the same, a non-zero value otherwise. */ #define strcoll strcmp /** * @brief Copy the string source into the string destination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @return A pointer to the end (the address of the terminating null byte) * of the copied string. */ char * stpcpy(char *destination, const char *source); /** * @brief Copy size bytes from the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * If size is less than the length of the source, then * the remaining characters in destination will be filled with '\0' * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the end (the address of the terminating null byte) * of the copied string. */ char * stpncpy(char *destination, const char *source, size_t size); /** * @brief Converts every character of a null-terminated string into lowercase * * Convertion is done in place. Only uppercase latin characters * will become lowercase, all other characters will remain * the same. * * @param string the string we want to convert to lowercase. * @return The same pointer as the one passed in parameters */ char * strlwr(char *string); /** * @brief Converts every character of a null-terminated string into lowercase * * Convertion is done in place. Only uppercase latin characters * will become lowercase, all other characters will remain * the same. * * @param string the string we want to convert to lowercase. * @return The same pointer as the one passed in parameters */ char * strupr(char *string); /** * @brief Reverses the order of characters in the string * * For example, a string "Hello" becomes "olleH". The NULL character at the end * of the string remains at the end. * * @param string the string we want to reverse * @return The same pointer as the one passed in parameters */ char * strrev(char *string); /** * @brief Returns a string corresponding to the error number * * Warning : the returned pointer should be duplicated if the user ever needs to modify it * * @param errnum number of error * @return the pointer to the message corresponding to the errnum or NULL if none was found */ char * strerror(int errnum); /** * @brief Returns a pointer to a new string which is a duplicate of the argument * * Warning : Memory for the new string is obtained with buddy_alloc() //TODO buddy_alloc/malloc for now? * and should be freed with buddy_free(). * buddy_init() should be called before calling strerror(). * * @param string string to duplicate * @return the pointer to the duplicate of the argument string or NULL if couldn't allocate enough memory space */ // char *strdup(const char *string); /** * @brief Returns a pointer to a new string which is a duplicate of the argument (copies at most n bytes) * * Warning : Memory for the new string is obtained with buddy_alloc() //TODO buddy_alloc/malloc for now? * and should be freed with buddy_free(). * buddy_init() should be called before calling strerror(). * * @param string string to duplicate * @param n max number of characters to duplicate * @return the pointer to the duplicate of the argument string or NULL if couldn't allocate enough memory space */ // char *strndup(const char *string, size_t n); /** * @brief Calculates the length of the longest prefix of string which consists entirely of bytes in accept. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param accept key characters that the longest prefix consists of * @return the index of the first character in string that is not in accept */ size_t strspn(const char *string, const char *accept); /** * @brief Calculates the length of the longest prefix of string which consists entirely of bytes not in reject. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param reject key characters that must not be in the longest prefix * @return the index of the first character in string that is the same as any of the ones in reject */ size_t strcspn(const char *string, const char *reject); /** * @brief Locates the first occurrence in the target string of any of the bytes in the string accept. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param accept key characters * @return a pointer to the byte in string that matches one of the bytes in accept, or NULL if no such byte is found. */ char * strpbrk(const char *string, const char *accept); /** * @brief Finds the first occurrence of the substring needle in the string haystack. * * If needle is an empty string, the result will be the same pointer as the one passed to haystack * This function uses KMP algorithm, and thereby uses more memory space * * @param haystack the target string where we look for a pattern * @param needle pattern to look for * @return a pointer to the beginning of the located substring, or NULL if the substring is not found */ char * strstr(const char *haystack, const char *needle); /** * @brief Extracts a token from a string * * The strtok_r() function breaks a string into a sequence of zero or more nonempty tokens. * * On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored (modified * internally). In each subsequent call that should parse the same string, str must be NULL and saveptr should be unchanged since * the previous call. * * The caller may specify different strings in delim in successive calls that parse the same string. For instance, if string is * "a,b,c d e f,g", by calling strtok_r() only with "," delimiter will create 4 tokens, but if the user calls it 2 times with "," * delimiter and then the rest with " " delimiter, 6 tokens wil be created : "a","b","c","d","e","f,g" ("f,g" is indeed one token * as strtok_r() was called with " " delimiter). * * Each call to strtok_r() returns a pointer to a null-terminated string containing the next token. This string does not include * the delimiting byte. If no more tokens are found, strtok_r() returns NULL. * * A sequence of calls to strtok_r() that operate on the same string maintains a pointer that determines the point from which to * start searching for the next token. The first call to strtok_r() sets this pointer to point to the first byte of the string. * The start of the next token is determined by scanning forward for the next nondelimiter byte in str. If such a byte is found, * it is taken as the start of the next token. If no such byte is found, then there are no more tokens, and strtok_r() returns * NULL. (A string that is empty or that contains only delimiters will thus cause strtok() to return NULL on the first call.) * * The end of each token is found by scanning forward until either the next delimiter byte is found or until the terminating null * byte ('\0') is encountered. If a delimiter byte is found, it is OVERWRITTEN with a null byte to terminate the current token, * and strtok_r() saves a pointer to the following byte; that pointer will be used as the starting point when searching for the * next token. In this case, strtok_r() returns a pointer to the start of the found token. * * From the above description, it follows that a sequence of two or more contiguous delimiter bytes in the parsed string is * considered to be a single delimiter, and that delimiter bytes at the start or end of the string are ignored. Put another way: * the tokens returned by strtok() are always nonempty strings. * * Different strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr arguments. * * Warning : * strtok_r modifies str * identity of delimiter bytes is lost (i.e. most of them will be replaced by '\0' in str) * if NULL is passed as the first argument for the FIRST call, *saveptr (not saveptr) should also be NULL * * @param str string to extract tokens from * @param delim string that contains bytes that would serve as delimiters * @param saveptr pointer used internally by strtok_r in order to maintain context between successive calls that parse the same * string * @return a pointer to the beginning of the next token terminated by '\0' or NULL if there are no more tokens */ char * strtok_r(char *str, const char *delim, char **saveptr); /** * @brief Extracts a token from a string * * If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token * in the string *stringp, that is delimited by one of the bytes in the string delim. This token is terminated by overwriting the * delimiter with a null byte ('\0'), and *stringp is updated to point past the token. In case no delimiter was found, the token * is taken to be the entire string *stringp, and *stringp is made NULL. * * Warning: * strsep() modifies its first parameter * identity of delimiter bytes is lost (they will be replaced by '\0' in *stringp) * * @param stringp pointer to a string (because string will be modified) to extract tokens from * @param delim string that contains bytes that would serve as delimiters * @return a pointer to the found null-terminated token, that is, it returns the original value of *stringp */ char * strsep(char **stringp, const char *delim); #endif /* DPUSYSCORE_STRING_H */ ================================================ FILE: golang/uPIMulator/sdk/stdlib/strlen.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include size_t strlen(const char *string) { const char *ptr = string; while (*ptr != '\0') { ptr++; } return ptr - string; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strlwr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strlwr(char *string) { char *ptr = string; char c; while ((c = *ptr) != '\0') { *ptr = tolower(c); ptr++; } return string; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strncat.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strncat(char *destination, const char *source, size_t size) { size_t length = strlen(destination); size_t i; for (i = 0; (i < size) && (source[i] != '\0'); i++) { destination[length + i] = source[i]; } destination[length + i] = '\0'; return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strncmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int strncmp(const char *string1, const char *string2, size_t size) { for (size_t len = 0; len < size; ++len) { unsigned char c1 = string1[len]; unsigned char c2 = string2[len]; if (((c1 - c2) != 0) || (c1 == '\0')) { return c1 - c2; } } return 0; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strncpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strncpy(char *destination, const char *source, size_t size) { char *ptr = destination; char c = *source; size_t each_byte; for (each_byte = 0; each_byte < size; ++each_byte) { if (c == '\0') { for (; each_byte < size; ++each_byte) { *ptr = '\0'; ptr++; } return destination; } *ptr = c; ptr++; source++; c = *source; } return destination; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strndup.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" #include "buddy_alloc.h" char * strndup(const char *string, size_t n) { size_t length = strnlen(string, n); char *result = buddy_alloc(length + 1); if (result != NULL) { memcpy(result, string, length); ((char *)result)[length + 1] = '\0'; } return result; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strnlen.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include size_t strnlen(const char *string, size_t max_len) { size_t len = 0; while ((string[len] != '\0') && len < max_len) { len++; } return len; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strpbrk.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include char * strpbrk(const char *string, const char *accept) { string += strcspn(string, accept); return *string ? (char *)string : NULL; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strrchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strrchr(char *string, int character) { char *pos = NULL; char *ptr = string; unsigned char c; do { c = *ptr; if (c == character) { pos = ptr; } ptr++; } while (c != '\0'); return pos; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strrev.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strrev(char *string) { size_t length = strlen(string); for (size_t each_char = 0; each_char < length / 2; ++each_char) { char c = string[each_char]; string[each_char] = string[length - each_char - 1]; string[length - each_char - 1] = c; } return string; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strsep.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strsep(char **stringp, const char *delim) { if (*stringp == NULL) { return NULL; } char *original = *stringp; char *delim_ptr = strpbrk(*stringp, delim); if (delim_ptr == NULL) { *stringp = NULL; } else { *delim_ptr = '\0'; *stringp = delim_ptr + 1; } return original; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strspn.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include // TODO Possible optimization: // use of the table of indexation that indicates if the character should or should not be accepted/rejected // in this case we will need 128 bits (as there are 128 ascii characters) ( = 16 bytes = 4 words ) per runtime // => 4x24 = 96 words of 32 bits. // // TODO Another solution would be to stock this table only temporarily with the allocation function, but, currently, it's not an // option. size_t strspn(const char *string, const char *accept) { size_t prefix_length; for (prefix_length = 0; string[prefix_length] != '\0'; ++prefix_length) { char c = string[prefix_length]; unsigned int accept_index = 0; while (true) { char a = accept[accept_index]; if (c == a) { break; } if (a == '\0') { return prefix_length; } accept_index++; } } return prefix_length; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strstr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "stdbool.h" #include "string.h" #include "buddy_alloc.h" char * strstr(const char *haystack, const char *needle) { char *current_needle = (char *)needle; char *start_haystack = (char *)haystack; char *current_haystack = start_haystack; while (true) { char needle_char = *current_needle; if (needle_char == '\0') { return start_haystack; } char haystack_char = *current_haystack; if (haystack_char == needle_char) { current_haystack++; current_needle++; } else if (haystack_char == '\0') { return NULL; } else { current_needle = (char *)needle; current_haystack = ++start_haystack; } } } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strtok_r.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" char * strtok_r(char *str, const char *delim, char **saveptr) { char *end; if (str == NULL) { str = *saveptr; } if (*str == '\0') { *saveptr = str; return NULL; } str += strspn(str, delim); if (*str == '\0') { *saveptr = str; return NULL; } end = str + strcspn(str, delim); if (*end == '\0') { *saveptr = end; return str; } *end = '\0'; *saveptr = end + 1; return str; } ================================================ FILE: golang/uPIMulator/sdk/stdlib/strtol.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ //// //////TODO : **endptr //// ////#include ////#include "ctype.h" ////#include "limits.h" //// ////static long overflow(int sign) ////{ //// if(sign) //// return INT64_MAX; //// else //// return INT64_MIN; //// //// ////} //// ////long strtol(const char *nptr, char **endptr, int base) ////{ //// if(nptr == NULL) //// return 0; //// unsigned long result = 0; //// int sign = 1; //// int i = 0; ////// while(isspace(nptr[i])) ////// i++; //// ////// switch(nptr[i]){ ////// case '-' : ////// sign = 0; //we change sign only when '-' was encountered ////// case '+' : ////// i++; //we increment i in both cases ////// } //// ////// ////// if((base == 16 ) && (nptr[i] == '0') && (nptr[i+1] == 'x')) ////// i+=2; ////// else if(base == 0){ ////// if(nptr[i] == '0'){ ////// base = 8; ////// i++; ////// if(nptr[i+1] == 'x'){ ////// base = 16; ////// i++; ////// } ////// } ////// else ////// base = 10; ////// } //// ////// switch(base) { ////// case 10 : //// while(((nptr[i]>>4) == 0x3) && ((nptr[i] & 0xf)<=9)){ //// if((unsigned long)result>>60){ //// return overflow(sign); //// } //// //// result = (unsigned long)(result<<1) + (unsigned long)(result<<3) + (unsigned long) nptr[i] - (unsigned long) ///'0'; ////// if((unsigned long)result>>63){ ////// return overflow(sign); ////// } //// i++; //// } ////// break; ////// case 2 : ////// while((nptr[i] & 0xfe) == 0x30){ ////// result = (result<<1) + (unsigned long)(nptr[i] & 0x1); ////// i++; ////// } ////// break; ////// case 4 : ////// while((nptr[i] & 0xfc) == 0x30){ ////// result = (result<<2) + (unsigned long)(nptr[i] & 0x3); ////// i++; ////// } ////// break; ////// case 8 : ////// while((nptr[i] & 0xf8) == 0x30){ ////// result = (result<<3) + (unsigned long)(nptr[i] & 0x7); ////// i++; ////// } ////// break; ////// case 16 : ////// while(((nptr[i]>='0') && (nptr[i]<='9')) || ((nptr[i]>='a') && (nptr[i]<='f')) || ((nptr[i]>='A') && ///(nptr[i]<='F')) ){ ////// unsigned long digit = ((nptr[i]>='0') && (nptr[i]<='9')) ? (unsigned long)(nptr[i] - '0') : (unsigned /// long)((nptr[i] & 0xf) + 10); ////// result = result<<4; ////// result = result + digit; ////// i++; ////// } ////// break; ////// default : ////// if(base < 2 || base > 36){ //base 0 has already been replaced by 8,10 or 16 ////// //TODO!!! ////// break; ////// } ////// } //// ////// if(sign == 0) ////// return (long)0 - (long)result; ////// else //// return (long) result; //// ////} //// // // // //// // //// Copyright (c) 2014-2019 - UPMEM // //// // //#include // //#include "limits.h" // //#include "ctype.h" // // static long overflow(int sign) // //{ // // if(sign) // // return INT64_MAX; // // else // // return INT64_MIN; // //} // // long int strtol(const char *nptr, char **endptr, int base) // //{ // // if(nptr == NULL) // // return 0; // // int sign = 1; // // int i=0; // // long result = 0; // // // // while((nptr[i]>='0') && (nptr[i]<='9')){ // // if(result>>60){ // // return overflow(sign); // // } // // result = (result<<1) + (result<<3)+ nptr[i] - '0'; // // i++; // // } // // return result; // //} ================================================ FILE: golang/uPIMulator/sdk/stdlib/strupr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strupr(char *string) { char *ptr = string; char c; while ((c = *ptr) != '\0') { *ptr = toupper(c); ptr++; } return string; } ================================================ FILE: golang/uPIMulator/sdk/syslib/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(syslib ${SRCS}) ================================================ FILE: golang/uPIMulator/sdk/syslib/absvdi2.c ================================================ /*===-- absvdi2.c - Implement __absvdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __absvdi2 for the compiler_rt library. * *===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: absolute value */ /* Effects: aborts if abs(x) < 0 */ COMPILER_RT_ABI di_int __absvdi2(di_int a) { const int N = (int)(sizeof(di_int) * CHAR_BIT); if (a == ((di_int)1 << (N - 1))) compilerrt_abort(); const di_int t = a >> (N - 1); return (a ^ t) - t; } ================================================ FILE: golang/uPIMulator/sdk/syslib/absvsi2.c ================================================ /* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __absvsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: absolute value */ /* Effects: aborts if abs(x) < 0 */ COMPILER_RT_ABI si_int __absvsi2(si_int a) { const int N = (int)(sizeof(si_int) * CHAR_BIT); if (a == (1 << (N - 1))) compilerrt_abort(); const si_int t = a >> (N - 1); return (a ^ t) - t; } ================================================ FILE: golang/uPIMulator/sdk/syslib/adddf3.c ================================================ //===-- lib/adddf3.c - Double-precision addition ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float addition with the IEEE-754 // default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_add_impl.inc" COMPILER_RT_ABI double __adddf3(double a, double b) { return __addXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_dadd(double a, double b) { return __adddf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/addsf3.c ================================================ //===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float addition with the IEEE-754 // default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_add_impl.inc" COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_fadd(float a, float b) { return __addsf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/addvdi3.c ================================================ /* ===-- addvdi3.c - Implement __addvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __addvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a + b */ /* Effects: aborts if a + b overflows */ COMPILER_RT_ABI di_int __addvdi3(di_int a, di_int b) { di_int s = (du_int)a + (du_int)b; if (b >= 0) { if (s < a) compilerrt_abort(); } else { if (s >= a) compilerrt_abort(); } return s; } ================================================ FILE: golang/uPIMulator/sdk/syslib/addvsi3.c ================================================ /* ===-- addvsi3.c - Implement __addvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __addvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a + b */ /* Effects: aborts if a + b overflows */ COMPILER_RT_ABI si_int __addvsi3(si_int a, si_int b) { si_int s = (su_int)a + (su_int)b; if (b >= 0) { if (s < a) compilerrt_abort(); } else { if (s >= a) compilerrt_abort(); } return s; } ================================================ FILE: golang/uPIMulator/sdk/syslib/alloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include volatile unsigned int __sys_heap_pointer = (unsigned int)(&__sys_heap_pointer_reset); ATOMIC_BIT_INIT(__heap_pointer); /* noinline, because part of grind tracked functions * Also used by seqread.inc */ void *__noinline mem_alloc_nolock(size_t size) { unsigned int pointer = __HEAP_POINTER; if (size != 0) { pointer = (pointer + 7) & ~7; unsigned int new_heap_pointer, dummy; __asm__ volatile("\tadd %[nhp], %[ptr], %[sz], nc, . + 2\n" "\tfault " __STR(__FAULT_ALLOC_HEAP_FULL__) "\n" "\tlbu %[dumb], %[nhp], -1\n" : [nhp] "=r"(new_heap_pointer), [dumb] "=r"(dummy) : [ptr] "r"(pointer), [sz] "r"(size)); __HEAP_POINTER = new_heap_pointer; } return (void *)pointer; } void * mem_alloc(size_t size) { ATOMIC_BIT_ACQUIRE(__heap_pointer); void *pointer = mem_alloc_nolock(size); ATOMIC_BIT_RELEASE(__heap_pointer); return pointer; } void * mem_reset() { ATOMIC_BIT_ACQUIRE(__heap_pointer); void *initial = &__sys_heap_pointer_reset; __sys_heap_pointer = (unsigned int)initial; ATOMIC_BIT_RELEASE(__heap_pointer); return (void *)initial; } ================================================ FILE: golang/uPIMulator/sdk/syslib/alloc.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ALLOC_H #define DPUSYSCORE_ALLOC_H /** * @file alloc.h * @brief Provides a way to manage heap allocation. * * @internal The heap is situated after the different kernel structures, local and global variables. * It can grow until reaching the end of the WRAM. A reboot of the DPU reset the Heap. * The current heap pointer can be accessed at the address defined by __HEAP_POINTER__. */ #include #include #include #include /** * @fn mem_alloc * @brief Allocates a buffer of the given size in the heap. * * The allocated buffer is aligned on 64 bits, in order to ensure compatibility * with the maximum buffer alignment constraint. As a consequence, a buffer * allocated with this function is also compatible with data transfers to/from MRAM. * * @param size the allocated buffer's size, in bytes * @throws a fault if there is no memory left * @return The allocated buffer address. */ void * mem_alloc(size_t size); /** * @fn mem_reset * @brief Resets the heap. * * Every allocated buffer becomes invalid, since subsequent allocations restart from the beginning * of the heap. * * @return The heap initial address. */ void * mem_reset(void); #endif /* DPUSYSCORE_ALLOC_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/ashldi3.c ================================================ /* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ashldi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a << b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __ashldi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); dwords input; dwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { result.s.low = 0; result.s.high = input.s.low << (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.low = input.s.low << b; result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b)); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_llsl(di_int a, si_int b) { return __ashldi3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/ashrdi3.c ================================================ /*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ashrdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: arithmetic a >> b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __ashrdi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); dwords input; dwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { /* result.s.high = input.s.high < 0 ? -1 : 0 */ result.s.high = input.s.high >> (bits_in_word - 1); result.s.low = input.s.high >> (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.high = input.s.high >> b; result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_lasr(di_int a, si_int b) { return __ashrdi3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/atomic_bit.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ATOMIC_BIT_H #define DPUSYSCORE_ATOMIC_BIT_H /** * @file atomic_bit.h * @brief Provides direct access to the atomic bits. */ #include #include #include #define ATOMIC_BIT_GET(_name) __CONCAT(__atomic_bit_, _name) #define ATOMIC_BIT_INIT(_name) uint8_t __atomic_bit ATOMIC_BIT_GET(_name) #define ATOMIC_BIT_EXTERN(_name) extern ATOMIC_BIT_INIT(_name) extern uint8_t __atomic_start_addr; #define ATOMIC_BIT_INDEX(_name) (&ATOMIC_BIT_GET(_name) - &__atomic_start_addr) #define __ATOMIC_BIT_ACQUIRE(_reg, _bit) \ __asm__ volatile("acquire %[areg], %[abit], nz, ." : : [areg] "r"(_reg), [abit] "i"(_bit)) #define __ATOMIC_BIT_RELEASE(_reg, _bit) \ __asm__ volatile("release %[areg], %[abit], nz, .+1" : : [areg] "r"(_reg), [abit] "i"(_bit)) #define ATOMIC_BIT_ACQUIRE(_name) __asm__ volatile("acquire zero, %[abit], nz, ." : : [abit] "i"(&ATOMIC_BIT_GET(_name))) #define ATOMIC_BIT_RELEASE(_name) __asm__ volatile("release zero, %[abit], nz, .+1" : : [abit] "i"(&ATOMIC_BIT_GET(_name))) #endif /* DPUSYSCORE_ATOMIC_BIT_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/atomics.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Prototype of function can be found here: https://llvm.org/docs/Atomics.html */ #include #include #define ATOMIC_BIT llvm_atomic_functions ATOMIC_BIT_INIT(ATOMIC_BIT); #define FOR_ALL_TYPES(fct) fct(1, char) fct(2, short) fct(4, int) fct(8, long long) #define PROLOGUE(ptr, load, n_type) \ n_type load; \ ATOMIC_BIT_ACQUIRE(ATOMIC_BIT); \ load = *ptr; #define EPILOGUE(load) \ ATOMIC_BIT_RELEASE(ATOMIC_BIT); \ return load; #define __SYNC_VAL_COMPARE_AND_SWAP_N(n_val, n_type) \ n_type __dpu_sync_val_compare_and_swap_##n_val(volatile n_type *ptr, n_type expected, n_type desired) \ { \ PROLOGUE(ptr, load, n_type); \ if (load == expected) \ *ptr = desired; \ EPILOGUE(load); \ } FOR_ALL_TYPES(__SYNC_VAL_COMPARE_AND_SWAP_N) #define __SYNC_LOCK_TEST_AND_SET_N(n_val, n_type) \ n_type __dpu_sync_lock_test_and_set_##n_val(volatile n_type *ptr, n_type val) \ { \ PROLOGUE(ptr, load, n_type); \ *ptr = val; \ EPILOGUE(load); \ } FOR_ALL_TYPES(__SYNC_LOCK_TEST_AND_SET_N) #define __SYNC_FETCH_AND_DO_N(fct, fct_name, n_val, n_type) \ n_type __dpu_sync_fetch_and_##fct_name##_##n_val(volatile n_type *ptr, n_type val) \ { \ PROLOGUE(ptr, load, n_type); \ *ptr = fct(load, val, n_type); \ EPILOGUE(load); \ } #define DO_ADD(a, b, n_type) ((a) + (b)) #define __SYNC_FETCH_AND_ADD_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_ADD, add, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_ADD_N) #define DO_SUB(a, b, n_type) ((a) - (b)) #define __SYNC_FETCH_AND_SUB_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_SUB, sub, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_SUB_N) #define DO_AND(a, b, n_type) ((a) & (b)) #define __SYNC_FETCH_AND_AND_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_AND, and, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_AND_N) #define DO_OR(a, b, n_type) ((a) | (b)) #define __SYNC_FETCH_AND_OR_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_OR, or, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_OR_N) #define DO_XOR(a, b, n_type) ((a) ^ (b)) #define __SYNC_FETCH_AND_XOR_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_XOR, xor, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_XOR_N) #define DO_NAND(a, b, n_type) (~((a) & (b))) #define __SYNC_FETCH_AND_NAND_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_NAND, nand, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_NAND_N) #define DO_MAX(a, b, n_type) ((a) > (b) ? (a) : (b)) #define __SYNC_FETCH_AND_MAX_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_MAX, max, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_MAX_N) #define DO_UMAX(a, b, n_type) (((unsigned n_type)(a)) > ((unsigned n_type)(b)) ? (a) : (b)) #define __SYNC_FETCH_AND_UMAX_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_UMAX, umax, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_UMAX_N) #define DO_MIN(a, b, n_type) ((a) > (b) ? (a) : (b)) #define __SYNC_FETCH_AND_MIN_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_MIN, min, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_MIN_N) #define DO_UMIN(a, b, n_type) (((unsigned n_type)(a)) > ((unsigned n_type)(b)) ? (a) : (b)) #define __SYNC_FETCH_AND_UMIN_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_UMIN, umin, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_UMIN_N) ================================================ FILE: golang/uPIMulator/sdk/syslib/attributes.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ATTRIBUTES_H #define DPUSYSCORE_ATTRIBUTES_H /** * @file attributes.h * @brief Provides common useful compiler attributes. */ #define DEPRECATED __attribute__((deprecated)) #if __STDC_VERSION__ >= 201112L #define __NO_RETURN _Noreturn #else #define __NO_RETURN #endif /* __STDC_VERSION__ */ #define __weak __attribute__((weak)) #define __section(s) __attribute__((section(s))) #define __aligned(a) __attribute__((aligned(a))) #define __used __attribute__((used)) #define __noinline __attribute__((noinline)) #define __atomic_bit __section(".atomic") #define __dma_aligned __aligned(8) #define __keep __used __section(".data.__sys_keep") #define __host __aligned(8) __used __section(".dpu_host") // Use this macro at variable definition to place this variable into the section // .data.immediate_memory and then makes it possible to use this variable // directly as an immediate into load store instructions (and then avoids the need // to move the address into a register before): immediate values are 12 signed bits // large. #define __lower_data(name) __attribute__((used, section(".data.immediate_memory." name))) /** * @def __mram_ptr * @brief An attribute declaring that a pointer is an address in MRAM. * * A typical usage is: ``unsigned int __mram_ptr * array32 = (unsigned int __mram_ptr *) 0xf000;`` * * Performing a cast between a pointer in MRAM and a pointer in WRAM is not allowed by the compiler. * */ #define __mram_ptr __attribute__((address_space(255))) #define __mram __mram_ptr __section(".mram") __dma_aligned __used #define __mram_noinit __mram_ptr __section(".mram.noinit") __dma_aligned __used #define __mram_keep __mram_ptr __section(".mram.keep") __dma_aligned __used #define __mram_noinit_keep __mram_ptr __section(".mram.noinit.keep") __dma_aligned __used #endif /* DPUSYSCORE_ATTRIBUTES_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/barrier.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include void barrier_wait(struct barrier_t *barrier) { unsigned char lock = barrier->lock; __acquire(lock, "0"); unsigned char count = barrier->count; unsigned char last = barrier->wait_queue; unsigned char first; thread_id_t tid = me(); /* Count = 1 means that I am the last to enter the barrier. * Need to wake up everybody.*/ if (unlikely(count == 1)) { if (likely(last != __EMPTY_WAIT_QUEUE)) { first = __WAIT_QUEUE_TABLE[last]; while (first != last) { __resume(first, "0"); first = __WAIT_QUEUE_TABLE[first]; } __resume(first, "0"); barrier->wait_queue = __EMPTY_WAIT_QUEUE; barrier->count = barrier->initial_count; } __release(lock, "0", __AT_NEXT_INSTRUCTION); } else { if (unlikely(last == __EMPTY_WAIT_QUEUE)) { __WAIT_QUEUE_TABLE[tid] = tid; } else { first = __WAIT_QUEUE_TABLE[last]; __WAIT_QUEUE_TABLE[tid] = first; __WAIT_QUEUE_TABLE[last] = tid; } barrier->wait_queue = tid; barrier->count = --count; __release(lock, "0", __AT_NEXT_INSTRUCTION); __stop(); } } ================================================ FILE: golang/uPIMulator/sdk/syslib/barrier.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_BARRIER_H #define DPUSYSCORE_BARRIER_H /** * @file barrier.h * @brief Synchronization with barriers. * * This synchronization mechanism allows to suspend a fixed number of tasklets until the expected number of subscribers is * present. When the required number of tasklets reached the barrier, the counter of the barrier will be reinitialised to the * original value. * * @internal The barriers are represented by a static value, defining the number of expected tasklets, a counter for the * current number of tasklets suspended by this barrier and a wait queue entry. * Whenever a new tasklet reaches the barrier (barrier_wait), the counter is decremented and the tasklet * is put into the wait queue. * If the counter is reduced to 0, all the tasklets that were suspended by this barrier will be resumed and * the counter will be reinitialised to its initial value. */ #include #include #include /** * @typedef barrier_t * @brief A barrier object, as declared by BARRIER_INIT. */ typedef struct barrier_t { uint8_t wait_queue; uint8_t count; uint8_t initial_count; uint8_t lock; } barrier_t; /** * @def BARRIER_INIT * @hideinitializer * @brief Declare and initialize a barrier associated to the given name. */ /* clang-format off */ #define BARRIER_INIT(_name, _counter) \ _Static_assert((_counter < 128) && (_counter >= -127), "barrier counter must be encoded on a byte"); \ ATOMIC_BIT_INIT(__CONCAT(barrier_, _name)); \ extern barrier_t _name; \ __asm__(".section .data." __STR(_name) "\n" \ ".type " __STR( _name) ",@object\n" \ ".globl " __STR( _name) "\n" \ ".p2align 2\n" __STR(_name) ":\n" \ ".byte 0xFF\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(ATOMIC_BIT_GET(__CONCAT(barrier_,_name))) "\n" \ ".size " __STR(_name) ", 4\n" \ ".text"); /* clang-format on */ /** * @fn barrier_wait * @brief Decrements the counter associated to the barrier and suspends the invoking tasklet. * * The counter of the barrier is decremented and the invoking tasklet is suspended until * the counter associated to the barrier is reduced to 0. * * @param barrier the barrier the tasklet will be associated to. */ void barrier_wait(barrier_t *barrier); #endif /* DPUSYSCORE_BARRIER_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/bswapdi2.c ================================================ /* ===-- bswapdi2.c - Implement __bswapdi2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __bswapdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" COMPILER_RT_ABI uint64_t __bswapdi2(uint64_t u) { return ((((u)&0xff00000000000000ULL) >> 56) | (((u)&0x00ff000000000000ULL) >> 40) | (((u)&0x0000ff0000000000ULL) >> 24) | (((u)&0x000000ff00000000ULL) >> 8) | (((u)&0x00000000ff000000ULL) << 8) | (((u)&0x0000000000ff0000ULL) << 24) | (((u)&0x000000000000ff00ULL) << 40) | (((u)&0x00000000000000ffULL) << 56)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/bswapsi2.c ================================================ /* ===-- bswapsi2.c - Implement __bswapsi2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __bswapsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" COMPILER_RT_ABI uint32_t __bswapsi2(uint32_t u) { return ((((u)&0xff000000) >> 24) | (((u)&0x00ff0000) >> 8) | (((u)&0x0000ff00) << 8) | (((u)&0x000000ff) << 24)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/buddy_alloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include //for mem_alloc #include //for size_t #include //for memset #include #include #include #include #include #include #include static unsigned char __buddy_init_done = 0; static int *__buddy_blocks = 0; static void *__buddy_heap_start = 0; static unsigned int __BUDDY_SIZE_OF_HEAP__ = 0; static unsigned char __BUDDY_MAX_POWER__ = 0; static unsigned char __BUDDY_NUMBER_OF_LEVELS__ = 0; ATOMIC_BIT_INIT(__buddy_lock); #define __BUDDY_DEPTH_LEVELS__ 3 #define __BUDDY_SHIFT_ADDRESS_TO_INDEX__ 4 static inline unsigned int next_power_of_2(int x) { // in order to find the size of the block to allocate we // count the number of leading zeros to get the correct // log2(size) // if size has only one "1" bit then we keep this power of 2 // otherwise, we add 1 unsigned int power_of_2 = 31 - count_leading_zeros(x); if (count_population(x) != 1) { power_of_2++; } return power_of_2; } /* * Note 1: * each bit represents the state of a block. It can equal either 0 or 1 and can represent 4 different states of a block : * target = 1 & buddy = 0 -> free : target block is [free] and can be * allocated without the need to cut the bigger block in half target = 1 & buddy = 1 -> not * in use : neither target nor its buddy are in use and bigger blocks must be checked * * target = 0 & both successors = 1 [not in use] -> allocated : this block is completely allocated * target = 0 & one or both of the successors = 0 [allocated] -> partially allocated : block is partially allocated i.e. * at least one of the sub-blocks is [allocated] * * Note 2: * Indexes of __buddy_blocks are indeed quite bizarre, which was a mistake during the conception stage. It doesn't change much. * Indexe_in_level start from 0 from left to right, but not for the 5 least significant bits where they still start from 0 but * from right to left */ void * safe_buddy_alloc(size_t size) { if ((size == 0) || (size > __BUDDY_SIZE_OF_HEAP__)) { errno = EINVAL; return NULL; } // we replace the size by the smallest 2 to the power of X such as it is greater than or equals the size // afterwards, we take X as power_of_2 and thereby find the correct level to search for free blocks: // blocks_level = __BUDDY_MAX_POWER__ - power_of_2 // for example if we try to allocate a block of 64 bytes (64=2^6), blocks_level = __BUDDY_MAX_POWER__ - 6 unsigned int power_of_2 = next_power_of_2(size); int blocks_level = __BUDDY_MAX_POWER__ - power_of_2; // if the size is smaller than the minimal size of // block divided by 2, then we can't allocate a block // so small and we have to allocate the block of the // minimal allowed size if (blocks_level >= __BUDDY_NUMBER_OF_LEVELS__) { blocks_level = __BUDDY_NUMBER_OF_LEVELS__ - 1; } // we browse all levels until we find the smallest free block that is big enough to contain "size" bytes for (int blocks_level_current = blocks_level; blocks_level_current >= 0; --blocks_level_current) { // we initialise index_in_level as the biggest index permitted in level unsigned int index_in_level = 1 << blocks_level_current; // levels 0-4 are in the same bitfield, // level 5 consists of a single bitfield // all other levels consist of 1<<(#level - 5) // bitfields unsigned int initial_number_of_current_bitfield = 0; unsigned int loaded_case_mask; switch (blocks_level_current) { default: initial_number_of_current_bitfield = ((1 << blocks_level_current) >> 5) - 1; loaded_case_mask = 0xFFFFFFFF; break; case 0: loaded_case_mask = 0x40000000; break; case 1: loaded_case_mask = 0x30000000; break; case 2: loaded_case_mask = 0x0F000000; break; case 3: loaded_case_mask = 0x00FF0000; break; case 4: loaded_case_mask = 0x0000FFFF; break; } for (int number_of_current_bitfield = initial_number_of_current_bitfield; number_of_current_bitfield >= 0; --number_of_current_bitfield, index_in_level -= 32) { // sizes of levels in __buddy_blocks is a geometric // series and thereby we can easily calculate the // number of bitfields that precede the current level unsigned int real_index = (1 << blocks_level_current) >> 5; // we load the bitfield unsigned int *initial_loaded_case_address = (unsigned int *)(__buddy_blocks + number_of_current_bitfield + real_index); // if we are in the very first bitfield // that contains first 5 levels, then we // need to make sure that buddy_free will // ignore the bits that represent blocks // that don't belong to blocks_level_current unsigned int loaded_case = *initial_loaded_case_address & loaded_case_mask; // this formula gives the number of zeros // before the first pair of free/allocated blocks // present in the current bitfield. If it equals // 32, then no such pair is present. unsigned int lz_before_first_pair_tmp = ((loaded_case << 1) ^ loaded_case) & 0xAAAAAAAA; if (lz_before_first_pair_tmp != 0) { unsigned int lz_before_first_pair = count_leading_zeros(lz_before_first_pair_tmp); index_in_level = index_in_level - lz_before_first_pair - 1; // if we are in the very first bitfield, // then we need to take into account the special // positioning of the 5 levels of blocks // inside this bitfield if (blocks_level_current < 5) { index_in_level += 1 << blocks_level_current; } unsigned int highlight_target_bit = 1 << index_in_level; // if current level is among first 4 //(5th is unnecessary to consider) // then we need to shift the mask if (blocks_level_current < 4) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) highlight_target_bit = highlight_target_bit << (32 - (2 << blocks_level_current)); } // we have the position of a pair of // free/allocated blocks, but we might // need to shift this position by 1 // if the target's buddy is the potential // block to allocate loaded_case = loaded_case & highlight_target_bit; if (loaded_case == 0) { highlight_target_bit = highlight_target_bit >> 1; index_in_level--; } // loaded_case have been modified if the first bitfield is handled loaded_case = *initial_loaded_case_address; // we mark the target bit as allocated loaded_case -= highlight_target_bit; *initial_loaded_case_address = loaded_case; // if we have already had a free block of the necessary size, // we return its address, otherwise we jump to //__buddy_alloc_break_loop and start cutting the blocks // in half until we get a block of the required size if (blocks_level == blocks_level_current) { return __buddy_heap_start + (index_in_level << (__BUDDY_MAX_POWER__ - blocks_level)); } // we have already set the block to 0 [partially allocated] // so we descend and start with the next one blocks_level_current++; while (blocks_level_current <= blocks_level) { index_in_level = index_in_level << 1; highlight_target_bit = 1 << index_in_level; // first 5 levels are stored in the same // bitfield. We need to handle this // special case and shift the mask int blocks_level_clamped = blocks_level_current - 4; if (blocks_level_clamped < 0) { highlight_target_bit = highlight_target_bit << (32 - (2 << blocks_level_current)); } // we load the bitfield // real_index is the offset in 32-bit words from the first bitfield in __buddy_blocks unsigned int real_index = 0; blocks_level_clamped--; if (blocks_level_clamped >= 0) { real_index = 1 << blocks_level_clamped; blocks_level_clamped = index_in_level >> 5; real_index += blocks_level_clamped; } loaded_case = __buddy_blocks[real_index]; // we mark the bit as allocated __buddy_blocks[real_index] = loaded_case - highlight_target_bit; // we continue to descend blocks_level_current++; } return __buddy_heap_start + (index_in_level << (__BUDDY_MAX_POWER__ - blocks_level)); } } } // if no level contains a big enough block, we return NULL errno = ENOMEM; return NULL; } typedef struct _buddy_search_context_t { unsigned int target_level; unsigned int real_index; unsigned int highlight_target_bit; unsigned int highlight_buddy_bit; } * buddy_search_context_t; int buddy_search_for_pointer(void *pointer, buddy_search_context_t context) { // if the pointer is not aligned to 64 bits, then it is corrupted // if the pointer is outside of the heap, we can do nothing if (((((unsigned int)pointer) & 7) != 0) || (pointer < __buddy_heap_start) || (pointer > (__buddy_heap_start + __BUDDY_SIZE_OF_HEAP__ - 1))) { errno = EINVAL; return -1; } // we transform the real address into an index for __buddy_blocks // index_in_level = (pointer - START_OF_HEAP)>>__BUDDY_SHIFT_ADDRESS_TO_INDEX__; unsigned int index_in_level = (pointer - __buddy_heap_start) >> __BUDDY_SHIFT_ADDRESS_TO_INDEX__; // we start to search for the pointer from the lowest level unsigned int target_level = __BUDDY_NUMBER_OF_LEVELS__ - 1; while (true) { // knowing the index_in_level we can calculate // highlight_target_bit and highlight_buddy_bit unsigned int highlight_target_bit = 1 << index_in_level; unsigned int highlight_buddy_bit; if ((count_leading_zeros(highlight_target_bit) & 1) == 0) { highlight_buddy_bit = highlight_target_bit >> 1; } else { highlight_buddy_bit = highlight_target_bit << 1; } // first 5 levels are stored in the // same bitfield. We need to handle // this special case and shift // the masks int target_level_clamped = target_level - 4; if (target_level_clamped < 0) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) unsigned int offset = 32 - (2 << target_level); highlight_buddy_bit = highlight_buddy_bit << offset; highlight_target_bit = highlight_target_bit << offset; } // we load a bitfield corresponding to the index // in __buddy_blocks // real_index is the offset in 32-bit words from the first bitfield in __buddy_blocks unsigned int real_index = 0; target_level_clamped--; if (target_level_clamped >= 0) { real_index = (1 << target_level_clamped); target_level_clamped = index_in_level >> 5; real_index = real_index + target_level_clamped; } unsigned int loaded_case = __buddy_blocks[real_index]; // We search for an allocated block // if we are on the highest level, we quit. if (((loaded_case & highlight_target_bit) == 0) || (target_level <= 0)) { context->target_level = target_level; context->real_index = real_index; context->highlight_target_bit = highlight_target_bit; context->highlight_buddy_bit = highlight_buddy_bit; return index_in_level; } // Condition required to avoid unwanted release if ((loaded_case & highlight_buddy_bit) == 0) { errno = EINVAL; return -1; } // we rise to the higher level index_in_level = index_in_level >> 1; target_level--; } } static void buddy_free_fusion_of_blocks(unsigned int index, buddy_search_context_t context) { unsigned int real_index = context->real_index; unsigned int current_level_freeing = context->target_level; unsigned int highlight_target_bit = context->highlight_target_bit; unsigned int highlight_buddy_bit = context->highlight_buddy_bit; unsigned int loaded_case = __buddy_blocks[real_index]; // if we are at the highest level, there is nothing to fuse while (current_level_freeing > 0) { // fusion occurs only when both blocks are free if (((loaded_case & highlight_target_bit) == 0) | ((loaded_case & highlight_buddy_bit) == 0)) { return; } // index of predecessor = index of successor >> 1 index = index >> 1; // we rise to the higher level current_level_freeing--; // knowing the index_in_level we can calculate // highlight_target_bit and highlight_buddy_bit highlight_target_bit = 1 << index; if ((count_leading_zeros(highlight_target_bit) & 1) == 0) { highlight_buddy_bit = highlight_target_bit >> 1; } else { highlight_buddy_bit = highlight_target_bit << 1; } // first 5 levels are stored in the same bitfield. // We need to handle this special case and shift // the masks int target_level_clamped = current_level_freeing - 4; if (target_level_clamped < 0) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) unsigned int offset = 32 - (2 << current_level_freeing); highlight_buddy_bit = highlight_buddy_bit << offset; highlight_target_bit = highlight_target_bit << offset; } // we load a bitfield corresponding // to the index in __buddy_blocks // // As both sub-blocks were freed, their "father" // must be marked as free. real_index = 0; target_level_clamped--; if (target_level_clamped >= 0) { real_index = (1 << target_level_clamped); target_level_clamped = index >> 5; real_index = real_index + target_level_clamped; } loaded_case = __buddy_blocks[real_index] | highlight_target_bit; __buddy_blocks[real_index] = loaded_case; } } void safe_buddy_free(void *pointer) { struct _buddy_search_context_t context; int index = buddy_search_for_pointer(pointer, &context); if (index != -1) { __buddy_blocks[context.real_index] |= context.highlight_target_bit; buddy_free_fusion_of_blocks(index, &context); } } // noinline, because part of grind tracked functions void __noinline * buddy_alloc(size_t size) { ATOMIC_BIT_ACQUIRE(__buddy_lock); void *result = safe_buddy_alloc(size); ATOMIC_BIT_RELEASE(__buddy_lock); return result; } // noinline, because part of grind tracked functions void __noinline buddy_free(void *pointer) { ATOMIC_BIT_ACQUIRE(__buddy_lock); safe_buddy_free(pointer); ATOMIC_BIT_RELEASE(__buddy_lock); } /*if the size of the smallest block needs to be changed, then only 2 things need to change : * __BUDDY_DEPTH_LEVELS__ here in buddy_init.c * __BUDDY_SHIFT_ADDRESS_TO_INDEX__ in buddy_defs.s * * When the minimal size of a block needs to be 32 bytes, then these two constants must equal 4 and 5 correspondingly * If minimal size needs to be 16 bytes, then these two constants must equal 3 and 4 correspondingly * If minimal size needs to be 8 bytes, then these two constants must equal 2 and 3 correspondingly * * Also, certain tests (Global, Reset, LevelByLevel) should also be changed. */ // TODO: Right now the size must be of power of 2 : 2048, 4096, 8192 and it won't work with other sizes. // TODO: There is no point in accepting other sizes, as the whole idea of having buddy allocation is based on it. // TODO: Right now the possibility of failure of mem_alloc is not taken into account of. // noinline, because part of grind tracked functions void __noinline buddy_init(size_t size_of_heap) { if (__buddy_init_done == 0) { ATOMIC_BIT_RELEASE(__buddy_lock); __BUDDY_SIZE_OF_HEAP__ = size_of_heap; unsigned int power_of_2 = count_leading_zeros(size_of_heap); __BUDDY_MAX_POWER__ = (31 - power_of_2); __BUDDY_NUMBER_OF_LEVELS__ = __BUDDY_MAX_POWER__ - __BUDDY_DEPTH_LEVELS__; unsigned int blocks_in_buddy_blocks = (1 << (__BUDDY_NUMBER_OF_LEVELS__ - 5)) << 2; __buddy_blocks = mem_alloc(size_of_heap + blocks_in_buddy_blocks); __buddy_heap_start = __buddy_blocks + (blocks_in_buddy_blocks >> 2); __buddy_blocks[0] = 0x7fffffff; // all bits except for the very first one must be set to 1 memset(&__buddy_blocks[1], 0xff, blocks_in_buddy_blocks - 4); // in order to initialize the __buddy_blocks structure __buddy_init_done = 1; } } // noinline, because part of grind tracked functions void __noinline buddy_reset() { ATOMIC_BIT_ACQUIRE(__buddy_lock); __buddy_blocks[0] = 0x7fffffff; // all bits except for the very first one must be set to 1 memset(&__buddy_blocks[1], 0xff, ((1 << (__BUDDY_NUMBER_OF_LEVELS__ - 5)) << 2) - 4); // in order to initialize the __buddy_blocks structure ATOMIC_BIT_RELEASE(__buddy_lock); } ================================================ FILE: golang/uPIMulator/sdk/syslib/buddy_alloc.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_BUDDY_ALLOC_H #define DPUSYSCORE_BUDDY_ALLOC_H /** * @file buddy_alloc.h * @brief Dynamic memory allocation and freeing. * * This library allows to create unique memory space in the heap to allocate and free * blocks of data. * * The memory space is initialized with buddy_init, which must be invoked only once during * the program's lifecycle. * * Functions can then dynamically get and free buffers, using buddy_alloc and buddy_free * respectively. * * In this implementation, the allocatable buffer size is chosen during the first call to buddy_init. * Tested sizes : 2048, 4096, 8192, 16384 and 32768 bytes * The allocated buffers are properly aligned on DMA transfer constraints, so that they can be * used as is in MRAM/WRAM transfer operations. */ /* * @internal The algorithm used in this implementation is Buddy memory allocation. * * A particularity of this implementation is that no headers are created and thereby * the memory consumption of the heap is reduced. The drawback is a slight slow-down * in speed of memory freeing. * * Warning : * Due to the particularities of the implementation (lack of headers), buddy_free * will always try to find a pointer to free. If the pointer given in the parameter * is not currently allocated by buddy_alloc or buddy_realloc, buddy_free * will do nothing. * */ #include /** * @fn buddy_init * @brief Allocates size_of_heap bytes for a heap that buddy_alloc can access to. * * Reserves memory space in the heap used to perform dynamic allocation and release of buffers. * * @param size_of_heap the size of heap in bytes that buddy_alloc can access to */ void buddy_init(size_t size_of_heap); /** * @fn buddy_reset * @brief Resets the heap. * * Quickly frees all pointers allocated by buddy_alloc or buddy_realloc. * Warning : currently buddy_reset() doesn't reset the size of the allocated heap. */ void buddy_reset(void); /** * @fn buddy_alloc * @brief Allocates a buffer of the given size in the heap, in a runtime-safe way. * * The allocated buffer is aligned on 64 bits, in order to ensure compatibility * with the maximum buffer alignment constraint. As a consequence, a buffer * allocated with this function is also compatible with data transfers to/from MRAM. * * Due to the idea of the buddy algorithm (to decrease external fragmentation), * the allocated blocks will be of size equal to a power of 2. In other words, * if the user allocates 33 bytes, 64 bytes will be allocated and when 2049 bytes * are requested, 4096 will be allocated. The user might want to take this into * account if she/he wishes to minimise the memory consumption. * * The minimal size of the allocated block is 16 bytes, but can easily be changed in * future implementations, so buddy_alloc is mostly adapted to allocating medium and * big structures, such as arrays containing more than 8 bytes (in order to make sure * that not too much memory space is wasted), binary trees or linked lists. * * If the size passed in parameter is less or equal to 0 or greater than the size of heap, * errno will be set to EINVAL and buddy_alloc will do nothing. * If buddy_alloc fails to find enough free memory space to allocate, errno will be * set to ENOMEM. * * @param size the allocated buffer's size, in bytes * @return A pointer to the allocated buffer if one was available, NULL otherwise. */ void * buddy_alloc(size_t size); /** * @fn buddy_free * @brief Frees a specified pointer, in a runtime-safe way. * * Warning : * Due to the particularities of the implementation (lack of headers), buddy_free * will always try to find a pointer to free and will see a pointer to the beginning of the * block in the same way as the pointer to anywhere inside the block. For example, if we have * allocated an int array[10], buddy_free will treat &array[0] the same way as &array[1] * or as the address of any other element inside this array and will free the whole block. * * If the pointer given in the parameter is not currently allocated by buddy_alloc or * buddy_realloc, buddy_free will do nothing. * * This function frees the memory space pointed to by pointer, which * must have been returned by a previous call to buddy_alloc or buddy_realloc * If it wasn't or if buddy_free has already been called for this pointer before, * then buddy_free will do nothing. If pointer is NULL, no operation is performed. * If the pointer passed as a parameter is not aligned to 64 bits or if it is outside * of the allocated heap errno will be set to EINVAL. * If buddy_free detects the attempt to free a non-allocated pointer, it will equally * set errno to EINVAL. * * @param pointer the pointer to the block to free */ void buddy_free(void *pointer); /** * @fn buddy_realloc * @brief Changes the size of the memory block pointed to by ptr to size bytes in a runtime-safe way. * * The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. * If the new size is larger than the old size, the added memory will not be initialized. * If ptr is NULL, then the call is equivalent to buddy_alloc(size) for all values of size. * If size is equal to zero, and ptr is not NULL, then the call is equivalent to * buddy_free(ptr) and the return value will be equal to the pointer passed as the parameter. Unless ptr * is NULL, it should have been returned by an earlier call to buddy_alloc() or buddy_realloc(). If it * wasn't, then buddy_realloc() will try to find this pointer among the allocated ones, but undefined behavior might * occur. * * If new size is smaller than the old size, then the remaining memory will potentially be released (depends * on the size of block). * * buddy_realloc() internally calls buddy_alloc and buddy_free and thereby will set errno * to ENOMEM or EINVAL on failure. * * @param ptr original pointer * @param size the new allocated buffer's size, in bytes * @return A new (or the same) pointer to the allocated buffer if one was available, NULL otherwise. */ void * buddy_realloc(void *ptr, size_t size); #endif /* DPUSYSCORE_BUDDY_ALLOC_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/buddy_realloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ // todo integrate in buddy_alloc.c, when we have reduced the buddy_alloc object file size #include #include #include #include //for memcpy #include #include #include ATOMIC_BIT_EXTERN(__buddy_lock); typedef struct _buddy_search_context_t { unsigned int target_level; unsigned int real_index; unsigned int highlight_target_bit; unsigned int highlight_buddy_bit; } * buddy_search_context_t; extern void * safe_buddy_alloc(size_t size); extern void safe_buddy_free(void *ptr); extern int buddy_search_for_pointer(void *ptr, buddy_search_context_t context); static int buddy_sizeofblock(void *pointer) { // We get the pointer (address) as the parameter and look for any allocated block that starts at this address. // If it is allocated, it will be found and its size will be returned. // If it is currently non allocated, buddy_sizeofblock will do nothing. struct _buddy_search_context_t dummy; int index = buddy_search_for_pointer(pointer, &dummy); if (index == -1) { return -1; } return 1 << (12 - index); } // noinline, because part of grind tracked functions void *__noinline buddy_realloc(void *ptr, size_t size) { ATOMIC_BIT_ACQUIRE(__buddy_lock); void *result = ptr; if (ptr == NULL) { // if ptr == NULL, then buddy_realloc must behave as buddy_alloc result = safe_buddy_alloc(size); ATOMIC_BIT_RELEASE(__buddy_lock); return result; // } if (size == 0) { // if size == 0 and ptr != NULL, then buddy_realloc behaves as buddy_free safe_buddy_free(ptr); // ATOMIC_BIT_RELEASE(__buddy_lock); // return ptr; // } size_t size_block = buddy_sizeofblock(ptr); if (size_block == ((size_t)-1)) { // size_block is set to -1 if ptr was not found among ATOMIC_BIT_RELEASE(__buddy_lock); // allocated pointers and that there is nothing to do return NULL; } if (size <= (size_block >> 1)) { // if newly allocated block is smaller than the currently allocated block size_block = size; // we will only copy "size" bytes } else if (size <= size_block) { // if newly allocated block is of the same size as the currently allocated block ATOMIC_BIT_RELEASE(__buddy_lock); // then there is no reason to do anything return ptr; } safe_buddy_free(ptr); // newly allocated block is either bigger or smaller than the currently allocated result = safe_buddy_alloc(size); // block and we need to call buddy_alloc to be sure that external fragmentation memcpy(result, ptr, size_block); // is avoided. ATOMIC_BIT_RELEASE(__buddy_lock); return result; } ================================================ FILE: golang/uPIMulator/sdk/syslib/built_ins.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef BUILT_INS_H #define BUILT_INS_H /** * @file built_ins.h * @brief Provides access to the built-in functions * * Automatically generated by the DPU assembler */ #define __builtin_nor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rrif(dc, ra, imm, false_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_u_rrr(dc, ra, rb) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rric(dc, ra, imm, log_set_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rrif(dc, ra, imm, false_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_u_rrr(dc, ra, rb) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rri(rc, ra, shift) __asm__("lsr %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zri(zero, ra, shift) __asm__("lsr %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrr(rc, ra, rb) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_zrr(zero, ra, rb) __asm__("lsr %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_boot_rici(ra, imm, boot_cc, pc) __asm__("boot %[ra_r32], " imm ", " boot_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sb_erir(endian, ra, off, rb) \ __asm__("sb " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sb_erii(endian, ra, off, imm) __asm__("sb " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sb_esir(endian, sa, off, rb) \ __asm__("sb " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sb_esii(endian, sa, off, imm) __asm__("sb " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lsl_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rri(dc, ra, shift) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_s_rrr(dc, ra, rb) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rri(rc, ra, shift) __asm__("lsl %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zri(zero, ra, shift) __asm__("lsl %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrr(rc, ra, rb) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_zrr(zero, ra, rb) __asm__("lsl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lhu_erri(endian, rc, ra, off) \ __asm__("lhu " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lhu_ersi(endian, rc, sa, off) \ __asm__("lhu " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_sw_erir(endian, ra, off, rb) \ __asm__("sw " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sw_erii(endian, ra, off, imm) __asm__("sw " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sw_esir(endian, sa, off, rb) \ __asm__("sw " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sw_esii(endian, sa, off, imm) __asm__("sw " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_asr_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rric(dc, ra, shift, log_set_cc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rri(dc, ra, shift) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_s_rrr(dc, ra, rb) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rri(dc, ra, shift) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_s_rrr(dc, ra, rb) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrr(rc, ra, rb) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_zrr(zero, ra, rb) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rric(dc, ra, shift, log_set_cc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rri(dc, ra, shift) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_u_rrr(dc, ra, rb) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_u_rrr(dc, ra, rb) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rri(rc, ra, imm) __asm__("addc %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zri(zero, rb, imm) __asm__("addc %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_addc_rrici(rc, ra, imm, add_nz_cc, pc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zrici(zero, ra, imm, add_nz_cc, pc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rric(rc, ra, imm, log_set_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zric(zero, ra, imm, log_set_cc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rrif(rc, ra, imm, false_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zrif(zero, ra, imm, false_cc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rrrci(rc, ra, rb, add_nz_cc, pc) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_zrrci(zero, ra, rb, add_nz_cc, pc) \ __asm__("addc %[zero], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rrrc(rc, ra, rb, log_set_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_zrrc(zero, ra, rb, log_set_cc) \ __asm__("addc %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rrr(rc, ra, rb) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_zrr(zero, ra, rb) __asm__("addc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_u_rrri(dc, rb, ra, shift) \ __asm__("lsl_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_time_cfg_u_rrci(dc, rb, true_cc, pc) \ __asm__("time_cfg.u %[dc_wr64], %[rb_wr32], " true_cc ", " pc "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_u_rr(dc, rb) __asm__("time_cfg.u %[dc_wr64], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrr(rc, ra, rb) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_zrr(zero, ra, rb) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_time_s_rci(dc, true_cc, pc) __asm__("time.s %[dc_wr64], " true_cc ", " pc "" : [dc_wr64] "=r"(dc)::) #define __builtin_time_s_r(dc) __asm__("time.s %[dc_wr64]" : [dc_wr64] "=r"(dc)::) #define __builtin_call_rri(rc, ra, off) __asm__("call %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_call_zri(zero, ra, off) __asm__("call %[zero], %[ra_r32], " off "" ::[ra_r32] "r"(ra) :) #define __builtin_call_rrr(rc, ra, rb) \ __asm__("call %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_call_zrr(zero, ra, rb) __asm__("call %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1 %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl1 %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rri(rc, ra, shift) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zri(zero, ra, shift) __asm__("lsl1 %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrr(rc, ra, rb) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_zrr(zero, ra, rb) __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rric(dc, ra, imm, log_set_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rrif(dc, ra, imm, false_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_u_rrr(dc, ra, rb) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rric(dc, ra, shift, log_set_cc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rri(dc, ra, shift) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_u_rrr(dc, ra, rb) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_stop_ci(boot_cc, pc) __asm__("stop " boot_cc ", " pc "" :::) #define __builtin_ldmai_rri(ra, rb, immDma) \ __asm__("ldmai %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rri(dc, ra, shift) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_s_rrr(dc, ra, rb) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_u_rrri(dc, rb, ra, shift) \ __asm__("lsr_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_time_cfg_rrci(rc, rb, true_cc, pc) \ __asm__("time_cfg %[rc_wr32], %[rb_wr32], " true_cc ", " pc "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_zrci(zero, rb, true_cc, pc) \ __asm__("time_cfg %[zero], %[rb_wr32], " true_cc ", " pc "" ::[rb_wr32] "r"(rb) :) #define __builtin_time_cfg_rr(rc, rb) __asm__("time_cfg %[rc_wr32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_zr(zero, rb) __asm__("time_cfg %[zero], %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_or_rri(rc, ra, imm) __asm__("or %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zri(zero, rb, imm) __asm__("or %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_or_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("or %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rric(rc, ra, imm, log_set_cc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zric(zero, ra, imm, log_set_cc) \ __asm__("or %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rrif(rc, ra, imm, false_cc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zrif(zero, ra, imm, false_cc) __asm__("or %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("or %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_rrrc(rc, ra, rb, log_set_cc) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_zrrc(zero, ra, rb, log_set_cc) \ __asm__("or %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_rrr(rc, ra, rb) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_zrr(zero, ra, rb) __asm__("or %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrr(rc, ra, rb) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_zrr(zero, ra, rb) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cao_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cao.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_u_rrc(dc, ra, log_set_cc) \ __asm__("cao.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_u_rr(dc, ra) __asm__("cao.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rric(rc, ra, shift, log_set_cc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zric(zero, ra, shift, log_set_cc) \ __asm__("lsrx %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rri(rc, ra, shift) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zri(zero, ra, shift) __asm__("lsrx %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_rrr(rc, ra, rb) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_zrr(zero, ra, rb) __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cls_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cls.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_u_rrc(dc, ra, log_set_cc) \ __asm__("cls.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_u_rr(dc, ra) __asm__("cls.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_mul_sh_sl_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_rrr(rc, ra, rb) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_zrr(zero, ra, rb) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sd_erir(endian, ra, off, db) \ __asm__("sd " endian ", %[ra_r32], " off ", %[db_wr64]" ::[ra_r32] "r"(ra), [db_wr64] "r"(db) :) #define __builtin_sd_erii(endian, ra, off, imm) __asm__("sd " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sd_esir(endian, sa, off, db) \ __asm__("sd " endian ", %[sa_r32], " off ", %[db_wr64]" ::[sa_r32] "r"(sa), [db_wr64] "r"(db) :) #define __builtin_sd_esii(endian, sa, off, imm) __asm__("sd " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lsrx_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rri(dc, ra, shift) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_s_rrr(dc, ra, rb) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_add_rrri(rc, rb, ra, shift) \ __asm__("lsl_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_add_zrri(zero, rb, ra, shift) \ __asm__("lsl_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rri(dc, ra, shift) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_s_rrr(dc, ra, rb) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sdma_rri(ra, rb, immDma) \ __asm__("sdma %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lhs_s_erri(endian, dc, ra, off) \ __asm__("lhs.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rri(dc, ra, shift) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_s_rrr(dc, ra, rb) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_s_rrr(dc, ra, rb) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr1x %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rri(rc, ra, shift) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zri(zero, ra, shift) __asm__("lsr1x %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrr(rc, ra, rb) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_zrr(zero, ra, rb) __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_u_rrr(dc, ra, rb) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbu_erri(endian, rc, ra, off) \ __asm__("lbu " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lbu_ersi(endian, rc, sa, off) \ __asm__("lbu " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_time_u_rci(dc, true_cc, pc) __asm__("time.u %[dc_wr64], " true_cc ", " pc "" : [dc_wr64] "=r"(dc)::) #define __builtin_time_u_r(dc) __asm__("time.u %[dc_wr64]" : [dc_wr64] "=r"(dc)::) #define __builtin_subc_s_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rirc(dc, imm, ra, sub_set_cc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rirf(dc, imm, ra, false_cc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrif(dc, ra, imm, false_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_s_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_s_rrr(dc, ra, rb) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clo.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_s_rrc(dc, ra, log_set_cc) \ __asm__("clo.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_s_rr(dc, ra) __asm__("clo.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrif(dc, ra, imm, false_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_s_rrr(dc, ra, rb) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrr(rc, ra, rb) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_zrr(zero, ra, rb) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrr(rc, ra, rb) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_zrr(zero, ra, rb) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_u_rrr(dc, ra, rb) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_s_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_s_rrr(dc, ra, rb) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrrc(rc, ra, rb, log_set_cc) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_zrrc(zero, ra, rb, log_set_cc) \ __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrr(rc, ra, rb) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_zrr(zero, ra, rb) __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rric(rc, ra, imm, log_set_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zric(zero, ra, imm, log_set_cc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rrif(rc, ra, imm, false_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zrif(zero, ra, imm, false_cc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("hash %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrrc(rc, ra, rb, log_set_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_zrrc(zero, ra, rb, log_set_cc) \ __asm__("hash %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrr(rc, ra, rb) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_zrr(zero, ra, rb) __asm__("hash %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rir(rc, imm, ra) __asm__("sub %[rc_wr32], " imm ", %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zir(zero, imm, rb) __asm__("sub %[zero], " imm ", %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_sub_rirci(rc, imm, ra, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirci(zero, imm, ra, sub_nz_cc, pc) \ __asm__("sub %[zero], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rirc(rc, imm, ra, sub_set_cc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirc(zero, imm, ra, sub_set_cc) \ __asm__("sub %[zero], " imm ", %[ra_r32], " sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rirf(rc, imm, ra, false_cc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirf(zero, imm, ra, false_cc) __asm__("sub %[zero], " imm ", %[ra_r32], " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rrici(rc, ra, imm, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zrici(zero, ra, imm, sub_nz_cc, pc) \ __asm__("sub %[zero], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rric(rc, ra, imm, ext_sub_set_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " ext_sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zric(zero, ra, imm, ext_sub_set_cc) \ __asm__("sub %[zero], %[ra_r32], " imm ", " ext_sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rrif(rc, ra, imm, false_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zrif(zero, ra, imm, false_cc) __asm__("sub %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_ssi(sc, sa, imm) __asm__("sub %[sc_wr32], %[sa_r32], " imm "" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa) :) #define __builtin_sub_sss(sc, sa, sb) \ __asm__("sub %[sc_wr32], %[sa_r32], %[sb_wr32]" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa), [sb_wr32] "r"(sb) :) #define __builtin_sub_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("sub %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rrrc(rc, ra, rb, ext_sub_set_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_zrrc(zero, ra, rb, ext_sub_set_cc) \ __asm__("sub %[zero], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rrr(rc, ra, rb) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_zrr(zero, ra, rb) __asm__("sub %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsb_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extsb %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extsb %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsb_rrc(rc, ra, log_set_cc) \ __asm__("extsb %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zrc(zero, ra, log_set_cc) __asm__("extsb %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsb_rr(rc, ra) __asm__("extsb %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zr(zero, ra) __asm__("extsb %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_andn_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rric(dc, ra, imm, log_set_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rrif(dc, ra, imm, false_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_s_rrr(dc, ra, rb) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_s_rrr(dc, ra, rb) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_movd_rrci(dc, db, true_false_cc, pc) \ __asm__("movd %[dc_wr64], %[db_wr64], " true_false_cc ", " pc "" : [dc_wr64] "=r"(dc) : [db_wr64] "r"(db) :) #define __builtin_lsl1x_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl1x %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rri(rc, ra, shift) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zri(zero, ra, shift) __asm__("lsl1x %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_rrr(rc, ra, rb) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_zrr(zero, ra, rb) __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rri(dc, ra, shift) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_u_rrr(dc, ra, rb) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_s_rrr(dc, ra, rb) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_s_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_s_rrr(dc, ra, rb) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_s_rrri(dc, rb, ra, shift) \ __asm__("lsl_sub.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_sats_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("sats.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_s_rrc(dc, ra, log_set_cc) \ __asm__("sats.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_s_rr(dc, ra) __asm__("sats.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirc(dc, imm, ra, sub_set_cc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirf(dc, imm, ra, false_cc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrif(dc, ra, imm, false_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_s_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_s_rrr(dc, ra, rb) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rri(rc, ra, imm) __asm__("and %[rc_wr32], %[ra_wr32], " imm "" : [rc_wr32] "=r"(rc) : [ra_wr32] "r"(ra) :) #define __builtin_and_zri(zero, rb, imm) __asm__("and %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_and_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("and %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rric(rc, ra, imm, log_set_cc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zric(zero, ra, imm, log_set_cc) \ __asm__("and %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rrif(rc, ra, imm, false_cc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zrif(zero, ra, imm, false_cc) __asm__("and %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("and %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rrrc(rc, ra, rb, log_set_cc) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_zrrc(zero, ra, rb, log_set_cc) \ __asm__("and %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rrr(rc, ra, rb) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_zrr(zero, ra, rb) __asm__("and %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cls_rrci(rc, ra, count_nz_cc, pc) \ __asm__("cls %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zrci(zero, ra, count_nz_cc, pc) \ __asm__("cls %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_cls_rrc(rc, ra, log_set_cc) \ __asm__("cls %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zrc(zero, ra, log_set_cc) __asm__("cls %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_cls_rr(rc, ra) __asm__("cls %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zr(zero, ra) __asm__("cls %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rsub_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("rsub %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_rrrc(rc, ra, rb, sub_set_cc) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_zrrc(zero, ra, rb, sub_set_cc) \ __asm__("rsub %[zero], %[ra_r32], %[rb_wr32], " sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_rrr(rc, ra, rb) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_zrr(zero, ra, rb) __asm__("rsub %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_div_step_rrrici(dc, ra, db, shift, div_cc, pc) \ __asm__("div_step %[dc_wr64], %[ra_r32], %[db_wr64], " shift ", " div_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [db_wr64] "r"(db) \ :) #define __builtin_rol_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rric(rc, ra, shift, log_set_cc) \ __asm__("rol %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zric(zero, ra, shift, log_set_cc) \ __asm__("rol %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rri(rc, ra, shift) __asm__("rol %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zri(zero, ra, shift) __asm__("rol %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("rol %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_rrrc(rc, ra, rb, log_set_cc) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_zrrc(zero, ra, rb, log_set_cc) \ __asm__("rol %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_rrr(rc, ra, rb) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_zrr(zero, ra, rb) __asm__("rol %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rri(dc, ra, shift) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_s_rrr(dc, ra, rb) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_swapd_rrci(dc, db, true_false_cc, pc) \ __asm__("swapd %[dc_wr64], %[db_wr64], " true_false_cc ", " pc "" : [dc_wr64] "=r"(dc) : [db_wr64] "r"(db) :) #define __builtin_add_s_rri(dc, rb, imm) \ __asm__("add.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_add_s_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rric(dc, ra, imm, log_set_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rrif(dc, ra, imm, false_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_s_rrr(dc, ra, rb) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rric(rc, ra, imm, log_set_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zric(zero, ra, imm, log_set_cc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rrif(rc, ra, imm, false_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zrif(zero, ra, imm, false_cc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nand %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nand %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrr(rc, ra, rb) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_zrr(zero, ra, rb) __asm__("nand %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbs_s_erri(endian, dc, ra, off) \ __asm__("lbs.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rri(dc, ra, shift) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_u_rrr(dc, ra, rb) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_s_erri(endian, dc, ra, off) \ __asm__("lw.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sb_id_erii(endian, ra, off, imm) __asm__("sb_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_and_s_rki(dc, ra, imm) __asm__("and.s %[dc_wr64], %[ra_r32], " imm "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rri(dc, rb, imm) \ __asm__("and.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_and_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rric(dc, ra, imm, log_set_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rrif(dc, ra, imm, false_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_s_rrr(dc, ra, rb) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nop_() __asm__("nop " :::) #define __builtin_sd_id_erii(endian, ra, off, imm) __asm__("sd_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sh_id_erii(endian, ra, off, imm) __asm__("sh_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rri(dc, ra, shift) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_u_rrr(dc, ra, rb) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsh_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extsh %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extsh %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsh_rrc(rc, ra, log_set_cc) \ __asm__("extsh %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zrc(zero, ra, log_set_cc) __asm__("extsh %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsh_rr(rc, ra) __asm__("extsh %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zr(zero, ra) __asm__("extsh %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rol_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_s_rrri(dc, rb, ra, shift) \ __asm__("rol_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_acquire_rici(ra, imm, acquire_cc, pc) \ __asm__("acquire %[ra_r32], " imm ", " acquire_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rri(rc, ra, imm) __asm__("xor %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zri(zero, rb, imm) __asm__("xor %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_xor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("xor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rric(rc, ra, imm, log_set_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zric(zero, ra, imm, log_set_cc) \ __asm__("xor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rrif(rc, ra, imm, false_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zrif(zero, ra, imm, false_cc) __asm__("xor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("xor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("xor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_rrr(rc, ra, rb) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_zrr(zero, ra, rb) __asm__("xor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rri(dc, ra, shift) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_u_rrr(dc, ra, rb) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rric(rc, ra, shift, log_set_cc) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zric(zero, ra, shift, log_set_cc) \ __asm__("lslx %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rri(rc, ra, shift) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zri(zero, ra, shift) __asm__("lslx %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lslx %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lslx %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrr(rc, ra, rb) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_zrr(zero, ra, rb) __asm__("lslx %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rric(dc, ra, shift, log_set_cc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rri(dc, ra, shift) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_u_rrr(dc, ra, rb) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rrif(dc, ra, imm, false_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_s_rrr(dc, ra, rb) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrr(rc, ra, rb) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_zrr(zero, ra, rb) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_u_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rirc(dc, imm, ra, sub_set_cc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rirf(dc, imm, ra, false_cc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrif(dc, ra, imm, false_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_u_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_u_rrr(dc, ra, rb) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rric(rc, ra, imm, log_set_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zric(zero, ra, imm, log_set_cc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rrif(rc, ra, imm, false_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zrif(zero, ra, imm, false_cc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nxor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nxor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrr(rc, ra, rb) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_zrr(zero, ra, rb) __asm__("nxor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rrif(dc, ra, imm, false_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_u_rrr(dc, ra, rb) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clo.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_u_rrc(dc, ra, log_set_cc) \ __asm__("clo.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_u_rr(dc, ra) __asm__("clo.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rric(dc, ra, imm, log_set_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrif(dc, ra, imm, false_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_s_rrr(dc, ra, rb) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsh_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extsh.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_s_rrc(dc, ra, log_set_cc) \ __asm__("extsh.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_s_rr(dc, ra) __asm__("extsh.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrif(dc, ra, imm, false_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_s_rrr(dc, ra, rb) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_u_rrr(dc, ra, rb) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rri(dc, ra, shift) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_s_rrr(dc, ra, rb) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_sub_rrri(rc, rb, ra, shift) \ __asm__("lsl_sub %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_sub_zrri(zero, rb, ra, shift) \ __asm__("lsl_sub %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_ror_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rric(rc, ra, shift, log_set_cc) \ __asm__("ror %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zric(zero, ra, shift, log_set_cc) \ __asm__("ror %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rri(rc, ra, shift) __asm__("ror %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zri(zero, ra, shift) __asm__("ror %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("ror %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_rrrc(rc, ra, rb, log_set_cc) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_zrrc(zero, ra, rb, log_set_cc) \ __asm__("ror %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_rrr(rc, ra, rb) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_zrr(zero, ra, rb) __asm__("ror %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_fault_i(imm) __asm__("fault " imm "" :::) #define __builtin_clz_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clz.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_s_rrc(dc, ra, log_set_cc) \ __asm__("clz.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_s_rr(dc, ra) __asm__("clz.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirc(dc, imm, ra, sub_set_cc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirf(dc, imm, ra, false_cc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrif(dc, ra, imm, false_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_u_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_u_rrr(dc, ra, rb) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_u_rrr(dc, ra, rb) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_s_rrr(dc, ra, rb) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_s_rrri(dc, rb, ra, shift) \ __asm__("lsl_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_mul_sh_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_rrr(rc, ra, rb) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_zrr(zero, ra, rb) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_s_rri(dc, rb, imm) __asm__("or.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_or_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rric(dc, ra, imm, log_set_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rrif(dc, ra, imm, false_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_s_rrr(dc, ra, rb) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sats_rrci(rc, ra, log_nz_cc, pc) \ __asm__("sats %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zrci(zero, ra, log_nz_cc, pc) \ __asm__("sats %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sats_rrc(rc, ra, log_set_cc) \ __asm__("sats %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zrc(zero, ra, log_set_cc) __asm__("sats %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sats_rr(rc, ra) __asm__("sats %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zr(zero, ra) __asm__("sats %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rsub_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_u_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_u_rrr(dc, ra, rb) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_erri(endian, rc, ra, off) \ __asm__("lw " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lw_ersi(endian, rc, sa, off) \ __asm__("lw " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_extsb_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extsb.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_s_rrc(dc, ra, log_set_cc) \ __asm__("extsb.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_s_rr(dc, ra) __asm__("extsb.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rric(dc, ra, shift, log_set_cc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rri(dc, ra, shift) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_s_rrr(dc, ra, rb) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrr(rc, ra, rb) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_zrr(zero, ra, rb) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_s_rrci(dc, rb, true_cc, pc) \ __asm__("time_cfg.s %[dc_wr64], %[rb_wr32], " true_cc ", " pc "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_s_rr(dc, rb) __asm__("time_cfg.s %[dc_wr64], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_s_rrr(dc, ra, rb) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_u_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_u_rrr(dc, ra, rb) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_rol_add_rrri(rc, rb, ra, shift) \ __asm__("rol_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_rol_add_zrri(zero, rb, ra, shift) \ __asm__("rol_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_cao_rrci(rc, ra, count_nz_cc, pc) \ __asm__("cao %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zrci(zero, ra, count_nz_cc, pc) \ __asm__("cao %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_cao_rrc(rc, ra, log_set_cc) \ __asm__("cao %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zrc(zero, ra, log_set_cc) __asm__("cao %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_cao_rr(rc, ra) __asm__("cao %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zr(zero, ra) __asm__("cao %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extuh %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extuh %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rrc(rc, ra, log_set_cc) \ __asm__("extuh %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zrc(zero, ra, log_set_cc) __asm__("extuh %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rr(rc, ra) __asm__("extuh %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zr(zero, ra) __asm__("extuh %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_mul_sl_sh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_s_rrr(dc, ra, rb) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rri(dc, ra, shift) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_u_rrr(dc, ra, rb) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rric(dc, ra, imm, log_set_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rrif(dc, ra, imm, false_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_s_rrr(dc, ra, rb) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_u_erri(endian, dc, ra, off) \ __asm__("lw.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_mul_sl_uh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_s_rrr(dc, ra, rb) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rri(dc, ra, shift) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_u_rrr(dc, ra, rb) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rrif(dc, ra, imm, false_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_s_rrr(dc, ra, rb) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rri(dc, ra, shift) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_u_rrr(dc, ra, rb) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_u_rki(dc, ra, imm) __asm__("and.u %[dc_wr64], %[ra_r32], " imm "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rri(dc, rb, imm) \ __asm__("and.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_and_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rric(dc, ra, imm, log_set_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rrif(dc, ra, imm, false_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_u_rrr(dc, ra, rb) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("orn %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rric(rc, ra, imm, log_set_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zric(zero, ra, imm, log_set_cc) \ __asm__("orn %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rrif(rc, ra, imm, false_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zrif(zero, ra, imm, false_cc) __asm__("orn %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("orn %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrrc(rc, ra, rb, log_set_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_zrrc(zero, ra, rb, log_set_cc) \ __asm__("orn %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrr(rc, ra, rb) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_zrr(zero, ra, rb) __asm__("orn %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_rrci(rc, ra, count_nz_cc, pc) \ __asm__("clo %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zrci(zero, ra, count_nz_cc, pc) \ __asm__("clo %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_clo_rrc(rc, ra, log_set_cc) \ __asm__("clo %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zrc(zero, ra, log_set_cc) __asm__("clo %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_clo_rr(rc, ra) __asm__("clo %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zr(zero, ra) __asm__("clo %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rol_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rric(dc, ra, shift, log_set_cc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rri(dc, ra, shift) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_s_rrr(dc, ra, rb) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrr(rc, ra, rb) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_zrr(zero, ra, rb) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_u_rrri(dc, rb, ra, shift) \ __asm__("rol_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_rrri(rc, rb, ra, shift) \ __asm__("lsr_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_zrri(zero, rb, ra, shift) \ __asm__("lsr_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rric(dc, ra, imm, log_set_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrif(dc, ra, imm, false_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_s_rrr(dc, ra, rb) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extub_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extub %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extub %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extub_rrc(rc, ra, log_set_cc) \ __asm__("extub %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zrc(zero, ra, log_set_cc) __asm__("extub %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extub_rr(rc, ra) __asm__("extub %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zr(zero, ra) __asm__("extub %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_sw_id_erii(endian, ra, off, imm) __asm__("sw_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_time_rci(rc, true_cc, pc) __asm__("time %[rc_wr32], " true_cc ", " pc "" : [rc_wr32] "=r"(rc)::) #define __builtin_time_zci(zero, true_cc, pc) __asm__("time %[zero], " true_cc ", " pc "" :::) #define __builtin_time_r(rc) __asm__("time %[rc_wr32]" : [rc_wr32] "=r"(rc)::) #define __builtin_time_z(zero) __asm__("time %[zero]" :::) #define __builtin_asr_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rric(rc, ra, shift, log_set_cc) \ __asm__("asr %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zric(zero, ra, shift, log_set_cc) \ __asm__("asr %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rri(rc, ra, shift) __asm__("asr %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zri(zero, ra, shift) __asm__("asr %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("asr %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_rrrc(rc, ra, rb, log_set_cc) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_zrrc(zero, ra, rb, log_set_cc) \ __asm__("asr %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_rrr(rc, ra, rb) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_zrr(zero, ra, rb) __asm__("asr %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ldma_rri(ra, rb, immDma) \ __asm__("ldma %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ld_erri(endian, dc, ra, off) \ __asm__("ld " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ld_ersi(endian, dc, sa, off) \ __asm__("ld " endian ", %[dc_wr64], %[sa_r32], " off "" : [dc_wr64] "=r"(dc) : [sa_r32] "r"(sa) :) #define __builtin_cls_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cls.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_s_rrc(dc, ra, log_set_cc) \ __asm__("cls.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_s_rr(dc, ra) __asm__("cls.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extuh.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rrc(dc, ra, log_set_cc) \ __asm__("extuh.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rr(dc, ra) __asm__("extuh.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("sats.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rrc(dc, ra, log_set_cc) \ __asm__("sats.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rr(dc, ra) __asm__("sats.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rric(dc, ra, imm, log_set_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrif(dc, ra, imm, false_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_u_rrr(dc, ra, rb) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rric(dc, ra, imm, log_set_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rrif(dc, ra, imm, false_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_u_rrr(dc, ra, rb) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rrif(dc, ra, imm, false_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_u_rrr(dc, ra, rb) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_u_rrri(dc, rb, ra, shift) \ __asm__("lsl_sub.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rri(dc, ra, shift) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_u_rrr(dc, ra, rb) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_resume_rici(ra, imm, boot_cc, pc) __asm__("resume %[ra_r32], " imm ", " boot_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lhs_erri(endian, rc, ra, off) \ __asm__("lhs " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lhs_ersi(endian, rc, sa, off) \ __asm__("lhs " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_cao_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cao.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_s_rrc(dc, ra, log_set_cc) \ __asm__("cao.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_s_rr(dc, ra) __asm__("cao.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clz.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rrc(dc, ra, log_set_cc) \ __asm__("clz.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rr(dc, ra) __asm__("clz.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1 %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr1 %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rri(rc, ra, shift) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zri(zero, ra, shift) __asm__("lsr1 %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_rrr(rc, ra, rb) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_zrr(zero, ra, rb) __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_u_rri(dc, rb, imm) \ __asm__("add.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_add_u_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rric(dc, ra, imm, log_set_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rrif(dc, ra, imm, false_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_u_rrr(dc, ra, rb) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrrc(rc, ra, rb, sub_set_cc) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_zrrc(zero, ra, rb, sub_set_cc) \ __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32], " sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrr(rc, ra, rb) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_zrr(zero, ra, rb) __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rri(rc, ra, imm) __asm__("add %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zri(zero, rb, imm) __asm__("add %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_add_rrici(rc, ra, imm, add_nz_cc, pc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zrici(zero, ra, imm, add_nz_cc, pc) \ __asm__("add %[zero], %[ra_r32], " imm ", " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_rric(rc, ra, imm, log_set_cc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zric(zero, ra, imm, log_set_cc) \ __asm__("add %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_rrif(rc, ra, imm, false_cc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zrif(zero, ra, imm, false_cc) __asm__("add %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_ssi(sc, sa, imm) __asm__("add %[sc_wr32], %[sa_r32], " imm "" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa) :) #define __builtin_add_rrrci(rc, ra, rb, add_nz_cc, pc) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_zrrci(zero, ra, rb, add_nz_cc, pc) \ __asm__("add %[zero], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rrrc(rc, ra, rb, log_set_cc) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_zrrc(zero, ra, rb, log_set_cc) \ __asm__("add %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rrr(rc, ra, rb) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_zrr(zero, ra, rb) __asm__("add %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_sss(sc, sa, sb) \ __asm__("add %[sc_wr32], %[sa_r32], %[sb_wr32]" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa), [sb_wr32] "r"(sb) :) #define __builtin_nor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rric(rc, ra, imm, log_set_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zric(zero, ra, imm, log_set_cc) \ __asm__("nor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rrif(rc, ra, imm, false_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zrif(zero, ra, imm, false_cc) __asm__("nor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_rrr(rc, ra, rb) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_zrr(zero, ra, rb) __asm__("nor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_u_rri(dc, rb, imm) __asm__("or.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_or_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rric(dc, ra, imm, log_set_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rrif(dc, ra, imm, false_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_u_rrr(dc, ra, rb) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rir(rc, imm, ra) __asm__("subc %[rc_wr32], " imm ", %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zir(zero, imm, rb) __asm__("subc %[zero], " imm ", %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_subc_rirci(rc, imm, ra, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirci(zero, imm, ra, sub_nz_cc, pc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rirc(rc, imm, ra, sub_set_cc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirc(zero, imm, ra, sub_set_cc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rirf(rc, imm, ra, false_cc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirf(zero, imm, ra, false_cc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrici(rc, ra, imm, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zrici(zero, ra, imm, sub_nz_cc, pc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rric(rc, ra, imm, ext_sub_set_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " ext_sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zric(zero, ra, imm, ext_sub_set_cc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " ext_sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrif(rc, ra, imm, false_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zrif(zero, ra, imm, false_cc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("subc %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rrrc(rc, ra, rb, ext_sub_set_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_zrrc(zero, ra, rb, ext_sub_set_cc) \ __asm__("subc %[zero], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rrr(rc, ra, rb) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_zrr(zero, ra, rb) __asm__("subc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbs_erri(endian, rc, ra, off) \ __asm__("lbs " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lbs_ersi(endian, rc, sa, off) \ __asm__("lbs " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_extub_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extub.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extub_u_rrc(dc, ra, log_set_cc) \ __asm__("extub.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extub_u_rr(dc, ra) __asm__("extub.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrif(dc, ra, imm, false_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_u_rrr(dc, ra, rb) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rric(rc, ra, imm, log_set_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zric(zero, ra, imm, log_set_cc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rrif(rc, ra, imm, false_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zrif(zero, ra, imm, false_cc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("andn %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrrc(rc, ra, rb, log_set_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_zrrc(zero, ra, rb, log_set_cc) \ __asm__("andn %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrr(rc, ra, rb) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_zrr(zero, ra, rb) __asm__("andn %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_release_rici(ra, imm, release_cc, pc) \ __asm__("release %[ra_r32], " imm ", " release_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_mul_sh_uh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_s_rrr(dc, ra, rb) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_s_rrri(dc, rb, ra, shift) \ __asm__("lsr_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_mul_sh_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_rrr(rc, ra, rb) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_zrr(zero, ra, rb) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrr(rc, ra, rb) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_zrr(zero, ra, rb) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_s_rrr(dc, ra, rb) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clz_rrci(rc, ra, count_nz_cc, pc) \ __asm__("clz %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zrci(zero, ra, count_nz_cc, pc) \ __asm__("clz %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_clz_rrc(rc, ra, log_set_cc) \ __asm__("clz %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zrc(zero, ra, log_set_cc) __asm__("clz %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_clz_rr(rc, ra) __asm__("clz %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zr(zero, ra) __asm__("clz %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_mul_step_rrrici(dc, ra, db, shift, boot_cc, pc) \ __asm__("mul_step %[dc_wr64], %[ra_r32], %[db_wr64], " shift ", " boot_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [db_wr64] "r"(db) \ :) #define __builtin_sh_erir(endian, ra, off, rb) \ __asm__("sh " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sh_erii(endian, ra, off, imm) __asm__("sh " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sh_esir(endian, sa, off, rb) \ __asm__("sh " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sh_esii(endian, sa, off, imm) __asm__("sh " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lbu_u_erri(endian, dc, ra, off) \ __asm__("lbu.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lhu_u_erri(endian, dc, ra, off) \ __asm__("lhu.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #endif /* BUILT_INS_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/clzdi2.c ================================================ /* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __clzdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of leading 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __clzdi2(di_int a) { dwords x; x.all = a; const si_int f = -(x.s.high == 0); return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); } ================================================ FILE: golang/uPIMulator/sdk/syslib/clzsi2.c ================================================ /* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __clzsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of leading 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __clzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0xFFFF0000) == 0) << 4; /* if (x is small) t = 16 else 0 */ x >>= 16 - t; /* x = [0 - 0xFFFF] */ su_int r = t; /* r = [0, 16] */ /* return r + clz(x) */ t = ((x & 0xFF00) == 0) << 3; x >>= 8 - t; /* x = [0 - 0xFF] */ r += t; /* r = [0, 8, 16, 24] */ /* return r + clz(x) */ t = ((x & 0xF0) == 0) << 2; x >>= 4 - t; /* x = [0 - 0xF] */ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ /* return r + clz(x) */ t = ((x & 0xC) == 0) << 1; x >>= 2 - t; /* x = [0 - 3] */ r += t; /* r = [0 - 30] and is even */ /* return r + clz(x) */ /* switch (x) * { * case 0: * return r + 2; * case 1: * return r + 1; * case 2: * case 3: * return r; * } */ return r + ((2 - x) & -((x & 2) == 0)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/cmpdi2.c ================================================ /* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __cmpdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 */ COMPILER_RT_ABI si_int __cmpdi2(di_int a, di_int b) { dwords x; x.all = a; dwords y; y.all = b; if (x.s.high < y.s.high) return 0; if (x.s.high > y.s.high) return 2; if (x.s.low < y.s.low) return 0; if (x.s.low > y.s.low) return 2; return 1; } #ifdef __ARM_EABI__ /* Returns: if (a < b) returns -1 * if (a == b) returns 0 * if (a > b) returns 1 */ COMPILER_RT_ABI si_int __aeabi_lcmp(di_int a, di_int b) { return __cmpdi2(a, b) - 1; } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/comparedf2.c ================================================ //===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // // This file implements the following soft-float comparison routines: // // __eqdf2 __gedf2 __unorddf2 // __ledf2 __gtdf2 // __ltdf2 // __nedf2 // // The semantics of the routines grouped in each column are identical, so there // is a single implementation for each, and wrappers to provide the other names. // // The main routines behave as follows: // // __ledf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // 1 if either a or b is NaN // // __gedf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // -1 if either a or b is NaN // // __unorddf2(a,b) returns 0 if both a and b are numbers // 1 if either a or b is NaN // // Note that __ledf2( ) and __gedf2( ) are identical except in their handling of // NaN values. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 }; COMPILER_RT_ABI enum LE_RESULT __ledf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; // If either a or b is NaN, they are unordered. if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; // If a and b are both zeros, they are equal. if ((aAbs | bAbs) == 0) return LE_EQUAL; // If at least one of a and b is positive, we get the same result comparing // a and b as signed integers as we would with a floating-point compare. if ((aInt & bInt) >= 0) { if (aInt < bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } // Otherwise, both are negative, so we need to flip the sense of the // comparison to get the correct result. (This assumes a twos- or ones- // complement integer representation; if integers are represented in a // sign-magnitude representation, then this flip is incorrect). else { if (aInt > bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } } #if defined(__ELF__) // Alias for libgcc compatibility FNALIAS(__cmpdf2, __ledf2); #endif enum GE_RESULT { GE_LESS = -1, GE_EQUAL = 0, GE_GREATER = 1, GE_UNORDERED = -1 // Note: different from LE_UNORDERED }; COMPILER_RT_ABI enum GE_RESULT __gedf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; if ((aAbs | bAbs) == 0) return GE_EQUAL; if ((aInt & bInt) >= 0) { if (aInt < bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } else { if (aInt > bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } } COMPILER_RT_ABI int __unorddf2(fp_t a, fp_t b) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; return aAbs > infRep || bAbs > infRep; } // The following are alternative names for the preceding routines. COMPILER_RT_ABI enum LE_RESULT __eqdf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __ltdf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __nedf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum GE_RESULT __gtdf2(fp_t a, fp_t b) { return __gedf2(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) { return __unorddf2(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/comparesf2.c ================================================ //===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the following soft-fp_t comparison routines: // // __eqsf2 __gesf2 __unordsf2 // __lesf2 __gtsf2 // __ltsf2 // __nesf2 // // The semantics of the routines grouped in each column are identical, so there // is a single implementation for each, and wrappers to provide the other names. // // The main routines behave as follows: // // __lesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // 1 if either a or b is NaN // // __gesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // -1 if either a or b is NaN // // __unordsf2(a,b) returns 0 if both a and b are numbers // 1 if either a or b is NaN // // Note that __lesf2( ) and __gesf2( ) are identical except in their handling of // NaN values. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 }; COMPILER_RT_ABI enum LE_RESULT __lesf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; // If either a or b is NaN, they are unordered. if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; // If a and b are both zeros, they are equal. if ((aAbs | bAbs) == 0) return LE_EQUAL; // If at least one of a and b is positive, we get the same result comparing // a and b as signed integers as we would with a fp_ting-point compare. if ((aInt & bInt) >= 0) { if (aInt < bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } // Otherwise, both are negative, so we need to flip the sense of the // comparison to get the correct result. (This assumes a twos- or ones- // complement integer representation; if integers are represented in a // sign-magnitude representation, then this flip is incorrect). else { if (aInt > bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } } #if defined(__ELF__) // Alias for libgcc compatibility FNALIAS(__cmpsf2, __lesf2); #endif enum GE_RESULT { GE_LESS = -1, GE_EQUAL = 0, GE_GREATER = 1, GE_UNORDERED = -1 // Note: different from LE_UNORDERED }; COMPILER_RT_ABI enum GE_RESULT __gesf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; if ((aAbs | bAbs) == 0) return GE_EQUAL; if ((aInt & bInt) >= 0) { if (aInt < bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } else { if (aInt > bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } } COMPILER_RT_ABI int __unordsf2(fp_t a, fp_t b) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; return aAbs > infRep || bAbs > infRep; } // The following are alternative names for the preceding routines. COMPILER_RT_ABI enum LE_RESULT __eqsf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __ltsf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __nesf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum GE_RESULT __gtsf2(fp_t a, fp_t b) { return __gesf2(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { return __unordsf2(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/ctzdi2.c ================================================ /* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ctzdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of trailing 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __ctzdi2(di_int a) { dwords x; x.all = a; const si_int f = -(x.s.low == 0); return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); } ================================================ FILE: golang/uPIMulator/sdk/syslib/ctzsi2.c ================================================ /* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ctzsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of trailing 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __ctzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0x0000FFFF) == 0) << 4; /* if (x has no small bits) t = 16 else 0 */ x >>= t; /* x = [0 - 0xFFFF] + higher garbage bits */ su_int r = t; /* r = [0, 16] */ /* return r + ctz(x) */ t = ((x & 0x00FF) == 0) << 3; x >>= t; /* x = [0 - 0xFF] + higher garbage bits */ r += t; /* r = [0, 8, 16, 24] */ /* return r + ctz(x) */ t = ((x & 0x0F) == 0) << 2; x >>= t; /* x = [0 - 0xF] + higher garbage bits */ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ /* return r + ctz(x) */ t = ((x & 0x3) == 0) << 1; x >>= t; x &= 3; /* x = [0 - 3] */ r += t; /* r = [0 - 30] and is even */ /* return r + ctz(x) */ /* The branch-less return statement below is equivalent * to the following switch statement: * switch (x) * { * case 0: * return r + 2; * case 2: * return r + 1; * case 1: * case 3: * return r; * } */ return r + ((2 - (x >> 1)) & -((x & 1) == 0)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/defs.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include int check_stack() { unsigned int stack_base, stack_size; int stack_limit, remaining; thread_id_t tid = me(); stack_base = __SP_TABLE__[tid].stack_ptr; stack_size = __SP_TABLE__[tid].stack_size; stack_limit = (int)(stack_base + stack_size); __asm__ volatile("sub %[r], %[l], r22" : [r] "=r"(remaining) : [l] "r"(stack_limit)); return remaining; } ================================================ FILE: golang/uPIMulator/sdk/syslib/defs.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DEFS_H #define DPUSYSCORE_DEFS_H #include #include #include #include /** * @file defs.h * @brief Miscellaneous system functions. * * General purpose definitions. */ #if __STDC_VERSION__ >= 201112L #define __ATTRIBUTE_NO_RETURN__ _Noreturn #else #define __ATTRIBUTE_NO_RETURN__ #endif /* __STDC_VERSION__ */ /** * @fn me * @internal This just returns the value of the special register id. * @return The current tasklet's sysname. */ static inline sysname_t me() { return __builtin_dpu_tid(); } /** * @fn halt * @brief Halts the DPU. * @throws FAULT_HALT always */ __ATTRIBUTE_NO_RETURN__ static inline void halt() { __builtin_trap(); __builtin_unreachable(); } /** * @fn check_stack * @return the number of unused 32-bits words in the current runtime's stack. * If the number is negative, it indicates by how much 32-bits words the stack overflowed. * * @internal This fetches the position of the next stack in memory from the Stack Pointer Table (cf. tasklet.h) * and compute the remaining bytes. */ int check_stack(); #endif /* DPUSYSCORE_DEFS_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/devprivate.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DEVPRIVATE_H #define DPUSYSCORE_DEVPRIVATE_H /** * @file devprivate.h * @brief Reserved for internal use ... please do not use those functions unless you know exactly what you do. */ /** * @def tell * @brief On a simulator, injects a tell instruction to print out developer debug info. * @nolink * * @warning This function will not work on a target different from simulator. * * @param reg a register * @param val a constant value */ #define tell(reg, val) __asm__("tell %[r], " val : : [r] "r"(reg) :) #endif /* DPUSYSCORE_DEVPRIVATE_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/div32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void __attribute__((naked, noinline, no_instrument_function)) __udiv32(void) { __asm__ volatile(" "__ADD_PROFILING_ENTRY__ " clz r3, r1, max, __udiv32_division_by_zero\n" // r3 = by how many the divider can be shifted on 32-bit " clz r4, r0\n" // r4 = number of useless bits of the dividend " sub r3, r4, r3, gtu, __udiv32_result_0\n" // r3 = the maximal shift to be done " move r4, r1\n" " move.u d0, r0\n" " jump r3, __udiv32_base\n" // As we will jump backward relatively to __udiv32_base " div_step d0, r4, d0, 31\n" " div_step d0, r4, d0, 30\n" " div_step d0, r4, d0, 29\n" " div_step d0, r4, d0, 28\n" " div_step d0, r4, d0, 27\n" " div_step d0, r4, d0, 26\n" " div_step d0, r4, d0, 25\n" " div_step d0, r4, d0, 24\n" " div_step d0, r4, d0, 23\n" " div_step d0, r4, d0, 22\n" " div_step d0, r4, d0, 21\n" " div_step d0, r4, d0, 20\n" " div_step d0, r4, d0, 19\n" " div_step d0, r4, d0, 18\n" " div_step d0, r4, d0, 17\n" " div_step d0, r4, d0, 16\n" " div_step d0, r4, d0, 15\n" " div_step d0, r4, d0, 14\n" " div_step d0, r4, d0, 13\n" " div_step d0, r4, d0, 12\n" " div_step d0, r4, d0, 11\n" " div_step d0, r4, d0, 10\n" " div_step d0, r4, d0, 9\n" " div_step d0, r4, d0, 8\n" " div_step d0, r4, d0, 7\n" " div_step d0, r4, d0, 6\n" " div_step d0, r4, d0, 5\n" " div_step d0, r4, d0, 4\n" " div_step d0, r4, d0, 3\n" " div_step d0, r4, d0, 2\n" " div_step d0, r4, d0, 1\n" "__udiv32_base:\n" " div_step d0, r4, d0, 0\n" "__udiv32_exit:\n" " jump r23\n" "__udiv32_result_0:\n" " move.u d0, r0, true, __udiv32_exit\n" "__udiv32_division_by_zero:\n" " fault "__STR(__FAULT_DIVISION_BY_ZERO__)); } void __attribute__((naked, noinline, no_instrument_function)) __div32(void) { __asm__ volatile(" "__ADD_PROFILING_ENTRY__ "sd r22, 0, d22\n" "add r22, r22, 8\n" // The quotient's sign depends on the sign of the dividend and divider... After few tries it sounds // like the quickest way to select the operators is to branch according to the cases. " clo r3, r0, z, __div32_pos_dividend\n" " clo r3, r1, z, __div32_neg_dividend_pos_divider\n" "__div32_neg_dividend_neg_divider:\n" // As a result, the quotient is positive and the remainder negative " neg r0, r0\n" " neg r1, r1\n" " call r23, __udiv32\n" " neg r1, r1, true, __div32_exit\n" "__div32_neg_dividend_pos_divider:\n" // As a result, the quotient is negative and the remainder negative " neg r0, r0\n" " call r23, __udiv32\n" " neg r1, r1\n" " neg r0, r0, true, __div32_exit\n" "__div32_pos_dividend:\n" " clo r3, r1, z, __div32_pos_dividend_pos_divider\n" " neg r1, r1\n" // As a result, the quotient is negative and the remainder positive " call r23, __udiv32\n" " neg r0, r0, true, __div32_exit\n" "__div32_pos_dividend_pos_divider:\n" // The dividend and divider are both positive " call r23, __udiv32\n" "__div32_exit:\n" " ld d22, r22, -8\n" " jump r23\n"); } ================================================ FILE: golang/uPIMulator/sdk/syslib/divdf3.c ================================================ //===-- lib/divdf3.c - Double-precision division ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float division // with the IEEE-754 default rounding (to nearest, ties to even). // // For simplicity, this implementation currently flushes denormals to zero. // It should be a fairly straightforward exercise to implement gradual // underflow with correct rounding. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __divdf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent - 1U >= maxExponent - 1U || bExponent - 1U >= maxExponent - 1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN / anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything / NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity / infinity = NaN if (bAbs == infRep) return fromRep(qnanRep); // infinity / anything else = +/- infinity else return fromRep(aAbs | quotientSign); } // anything else / infinity = +/- 0 if (bAbs == infRep) return fromRep(quotientSign); if (!aAbs) { // zero / zero = NaN if (!bAbs) return fromRep(qnanRep); // zero / anything else = +/- zero else return fromRep(quotientSign); } // anything else / zero = +/- infinity if (!bAbs) return fromRep(infRep | quotientSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale -= normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; int quotientExponent = aExponent - bExponent + scale; // Align the significand of b as a Q31 fixed-point number in the range // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // is accurate to about 3.5 binary digits. const uint32_t q31b = bSignificand >> 21; uint32_t recip32 = UINT32_C(0x7504f333) - q31b; // Now refine the reciprocal estimate using a Newton-Raphson iteration: // // x1 = x0 * (2 - x0 * b) // // This doubles the number of correct binary digits in the approximation // with each iteration, so after three iterations, we have about 28 binary // digits of accuracy. uint32_t correction32; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; // recip32 might have overflowed to exactly zero in the preceding // computation if the high word of b is exactly 1.0. This would sabotage // the full-width final stage of the computation that follows, so we adjust // recip32 downward by one bit. recip32--; // We need to perform one more iteration to get us to 56 binary digits; // The last iteration needs to happen with extra precision. const uint32_t q63blo = bSignificand << 11; uint64_t correction, reciprocal; correction = -((uint64_t)recip32 * q31b + ((uint64_t)recip32 * q63blo >> 32)); uint32_t cHi = correction >> 32; uint32_t cLo = correction; reciprocal = (uint64_t)recip32 * cHi + ((uint64_t)recip32 * cLo >> 32); // We already adjusted the 32-bit estimate, now we need to adjust the final // 64-bit reciprocal estimate downward to ensure that it is strictly smaller // than the infinitely precise exact reciprocal. Because the computation // of the Newton-Raphson step is truncating at every step, this adjustment // is small; most of the work is already done. reciprocal -= 2; // The numerical reciprocal is accurate to within 2^-56, lies in the // interval [0.5, 1.0), and is strictly smaller than the true reciprocal // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b // in Q53 with the following properties: // // 1. q < a/b // 2. q is in the interval [0.5, 2.0) // 3. the error in q is bounded away from 2^-53 (actually, we have a // couple of bits to spare, but this is all we need). // We need a 64 x 64 multiply high to compute q, which isn't a basic // operation in C, so we need to be a little bit fussy. rep_t quotient, quotientLo; wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo); // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). // In either case, we are going to compute a residual of the form // // r = a - q*b // // We know from the construction of q that r satisfies: // // 0 <= r < ulp(q)*b // // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we // already have the correct result. The exact halfway case cannot occur. // We also take this time to right shift quotient if it falls in the [1,2) // range and adjust the exponent accordingly. rep_t residual; if (quotient < (implicitBit << 1)) { residual = (aSignificand << 53) - quotient * bSignificand; quotientExponent--; } else { quotient >>= 1; residual = (aSignificand << 52) - quotient * bSignificand; } const int writtenExponent = quotientExponent + exponentBias; if (writtenExponent >= maxExponent) { // If we have overflowed the exponent, return infinity. return fromRep(infRep | quotientSign); } else if (writtenExponent < 1) { // Flush denormals to zero. In the future, it would be nice to add // code to round them correctly. return fromRep(quotientSign); } else { const bool round = (residual << 1) > bSignificand; // Clear the implicit bit rep_t absResult = quotient & significandMask; // Insert the exponent absResult |= (rep_t)writtenExponent << significandBits; // Round absResult += round; // Insert the sign and return const double result = fromRep(absResult | quotientSign); return result; } } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) { return __divdf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/divdi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 signed division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); int64_t __divdi3(int64_t dividend, int64_t divider) { if (dividend >= 0) { if (divider >= 0) { return __udiv64(dividend, divider, 0); } else { return -__udiv64(dividend, -divider, 0); } } else if (divider >= 0) { // Negative dividend, positive divider return -__udiv64(-dividend, divider, 0); } else { // Negative dividend, negative divider return __udiv64(-dividend, -divider, 0); } } ================================================ FILE: golang/uPIMulator/sdk/syslib/divmodsi4.c ================================================ /*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __divmodsi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b, *rem = a % b */ extern long __div32(int, int); COMPILER_RT_ABI si_int __divmodsi4(si_int a, si_int b, si_int *rem) { long res = __div32(a, b); *rem = (int)res; return (int)(res >> 32); } ================================================ FILE: golang/uPIMulator/sdk/syslib/divsf3.c ================================================ //===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float division // with the IEEE-754 default rounding (to nearest, ties to even). // // For simplicity, this implementation currently flushes denormals to zero. // It should be a fairly straightforward exercise to implement gradual // underflow with correct rounding. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent - 1U >= maxExponent - 1U || bExponent - 1U >= maxExponent - 1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN / anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything / NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity / infinity = NaN if (bAbs == infRep) return fromRep(qnanRep); // infinity / anything else = +/- infinity else return fromRep(aAbs | quotientSign); } // anything else / infinity = +/- 0 if (bAbs == infRep) return fromRep(quotientSign); if (!aAbs) { // zero / zero = NaN if (!bAbs) return fromRep(qnanRep); // zero / anything else = +/- zero else return fromRep(quotientSign); } // anything else / zero = +/- infinity if (!bAbs) return fromRep(infRep | quotientSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale -= normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; int quotientExponent = aExponent - bExponent + scale; // Align the significand of b as a Q31 fixed-point number in the range // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // is accurate to about 3.5 binary digits. uint32_t q31b = bSignificand << 8; uint32_t reciprocal = UINT32_C(0x7504f333) - q31b; // Now refine the reciprocal estimate using a Newton-Raphson iteration: // // x1 = x0 * (2 - x0 * b) // // This doubles the number of correct binary digits in the approximation // with each iteration, so after three iterations, we have about 28 binary // digits of accuracy. uint32_t correction; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; // Exhaustive testing shows that the error in reciprocal after three steps // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our // expectations. We bump the reciprocal by a tiny value to force the error // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to // be specific). This also causes 1/1 to give a sensible approximation // instead of zero (due to overflow). reciprocal -= 2; // The numerical reciprocal is accurate to within 2^-28, lies in the // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller // than the true reciprocal of b. Multiplying a by this reciprocal thus // gives a numerical q = a/b in Q24 with the following properties: // // 1. q < a/b // 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0) // 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes // from the fact that we truncate the product, and the 2^27 term // is the error in the reciprocal of b scaled by the maximum // possible value of a. As a consequence of this error bound, // either q or nextafter(q) is the correctly rounded rep_t quotient = (uint64_t)reciprocal * (aSignificand << 1) >> 32; // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). // In either case, we are going to compute a residual of the form // // r = a - q*b // // We know from the construction of q that r satisfies: // // 0 <= r < ulp(q)*b // // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we // already have the correct result. The exact halfway case cannot occur. // We also take this time to right shift quotient if it falls in the [1,2) // range and adjust the exponent accordingly. rep_t residual; if (quotient < (implicitBit << 1)) { residual = (aSignificand << 24) - quotient * bSignificand; quotientExponent--; } else { quotient >>= 1; residual = (aSignificand << 23) - quotient * bSignificand; } const int writtenExponent = quotientExponent + exponentBias; if (writtenExponent >= maxExponent) { // If we have overflowed the exponent, return infinity. return fromRep(infRep | quotientSign); } else if (writtenExponent < 1) { // Flush denormals to zero. In the future, it would be nice to add // code to round them correctly. return fromRep(quotientSign); } else { const bool round = (residual << 1) > bSignificand; // Clear the implicit bit rep_t absResult = quotient & significandMask; // Insert the exponent absResult |= (rep_t)writtenExponent << significandBits; // Round absResult += round; // Insert the sign and return return fromRep(absResult | quotientSign); } } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) { return __divsf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/divsi3.c ================================================ /* ===-- divsi3.c - Implement __divsi3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __divsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b */ COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) { const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1; si_int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */ si_int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ s_a ^= s_b; /* sign of quotient */ /* * On CPUs without unsigned hardware division support, * this calls __udivsi3 (notice the cast to su_int). * On CPUs with unsigned hardware division support, * this uses the unsigned division instruction. */ return ((su_int)a / (su_int)b ^ s_a) - s_a; /* negate if s_a == -1 */ } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_idiv(si_int a, si_int b) { return __divsi3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/dpuconst.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPUCONST_H #define DPUSYSCORE_DPUCONST_H #define __DPU_NUMBER_OF_THREADS 24 #define __DPU_MRAM_SIZE_LOG2 26 #endif /* DPUSYSCORE_DPUCONST_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/dpufault.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPUFAULT_H #define DPUSYSCORE_DPUFAULT_H // A list of "fault codes" #define __FAULT_ALLOC_HEAP_FULL__ 1 #define __FAULT_DIVISION_BY_ZERO__ 2 #define __FAULT_ASSERT_FAILED__ 3 // Used in the compiler to implement a trap #define __FAULT_HALT__ 4 #define __FAULT_PRINTF_OVERFLOW__ 5 #define __FAULT_ALREADY_PROFILING__ 6 #define __FAULT_NOT_PROFILING__ 7 #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/dpuruntime.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPURUNTIME_H #define DPUSYSCORE_DPURUNTIME_H #include #include #include #include #include // todo fix: This file should not be included by another syslib header file, only by source files (conflicting definitions). #define __INITIAL_HEAP_POINTER __sys_heap_pointer_reset #define __HEAP_POINTER __sys_heap_pointer #define __WAIT_QUEUE_TABLE __sys_wq_table #define __SP_TABLE__ __sys_thread_stack_table_ptr #define __STDOUT_BUFFER_STATE __stdout_buffer_state /* The order needs to match the __bootstrap function expectation */ typedef struct { uint32_t stack_size; uint32_t stack_ptr; } thread_stack_t; extern unsigned int __INITIAL_HEAP_POINTER; extern volatile unsigned int __HEAP_POINTER; extern unsigned char __WAIT_QUEUE_TABLE[]; extern thread_stack_t __SP_TABLE__[]; #define __acquire(base, off) __builtin_acquire_rici(base, off, "nz", __AT_THIS_INSTRUCTION) #define __release(base, off, at) __builtin_release_rici(base, off, "nz", at) #define __resume(base, off) __builtin_resume_rici(base, off, "nz", __AT_THIS_INSTRUCTION) #define __stop() __builtin_stop_ci("false", "0") #define __stop_at(label) __builtin_stop_ci("true", label) #define likely(x) __builtin_expect((x), 1) #define unlikely(x) __builtin_expect((x), 0) #define unreachable() __builtin_unreachable() #define count_leading_zeros(x) __builtin_clz(x) #define count_population(x) __builtin_popcount(x) #define __EMPTY_WAIT_QUEUE 0xFF #define __AT_THIS_INSTRUCTION ".+0" #define __AT_NEXT_INSTRUCTION ".+1" // Use this macro at the beginning of an assembly function in order to get profiled. #ifdef DPU_PROFILING #define __ADD_PROFILING_ENTRY__ "call r23, mcount\n" #else #define __ADD_PROFILING_ENTRY__ "\n" #endif #ifdef DPU_PROFILING /* Reset counter + count cycles */ #define __CONFIG_PERFCOUNTER_ENTRY__ \ " move r23, 3\n" \ " time_cfg zero, r23\n" #define __SAVE_PERFCOUNTER_ENTRY__ \ " time r23\n" \ " sw zero, perfcounter_end_value, r23\n" #else #define __CONFIG_PERFCOUNTER_ENTRY__ "\n" #define __SAVE_PERFCOUNTER_ENTRY__ "\n" #endif #endif /* DPUSYSCORE_DPURUNTIME_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/extendhfsf2.c ================================================ //===-- lib/extendhfsf2.c - half -> single conversion -------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // #define SRC_HALF #define DST_SINGLE #include "fp_extend_impl.inc" // Use a forwarding definition and noinline to implement a poor man's alias, // as there isn't a good cross-platform way of defining one. COMPILER_RT_ABI NOINLINE float __extendhfsf2(uint16_t a) { return __extendXfYf2__(a); } COMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) { return __extendhfsf2(a); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_h2f(uint16_t a) { return __extendhfsf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/extendsfdf2.c ================================================ //===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // #define SRC_SINGLE #define DST_DOUBLE #include "fp_extend_impl.inc" COMPILER_RT_ABI double __extendsfdf2(float a) { return __extendXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_f2d(float a) { return __extendsfdf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/ffsdi2.c ================================================ /* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffsdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffsdi2(di_int a) { dwords x; x.all = a; if (x.s.low == 0) { if (x.s.high == 0) return 0; return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT); } return __builtin_ctz(x.s.low) + 1; } ================================================ FILE: golang/uPIMulator/sdk/syslib/ffssi2.c ================================================ /* ===-- ffssi2.c - Implement __ffssi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffssi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffssi2(si_int a) { if (a == 0) { return 0; } return __builtin_ctz(a) + 1; } ================================================ FILE: golang/uPIMulator/sdk/syslib/ffsti2.c ================================================ /* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffsti2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #ifdef CRT_HAS_128BIT /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffsti2(ti_int a) { twords x; x.all = a; if (x.s.low == 0) { if (x.s.high == 0) return 0; return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT); } return __builtin_ctzll(x.s.low) + 1; } #endif /* CRT_HAS_128BIT */ ================================================ FILE: golang/uPIMulator/sdk/syslib/fixdfdi.c ================================================ /* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunsdfdi(double a); COMPILER_RT_ABI di_int __fixdfdi(double a) { if (a < 0.0) { return -__fixunsdfdi(-a); } return __fixunsdfdi(a); } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI di_int __fixdfdi(fp_t a) { return __fixint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI di_int #if defined(__SOFT_FP__) __aeabi_d2lz(fp_t a) { #else __aeabi_d2lz(double a) { #endif return __fixdfdi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixdfsi.c ================================================ /* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" typedef si_int fixint_t; typedef su_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI si_int __fixdfsi(fp_t a) { return __fixint(a); } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_d2iz(fp_t a) { return __fixdfsi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixsfdi.c ================================================ /* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunssfdi(float a); COMPILER_RT_ABI di_int __fixsfdi(float a) { if (a < 0.0f) { return -__fixunssfdi(-a); } return __fixunssfdi(a); } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI di_int __fixsfdi(fp_t a) { return __fixint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI di_int #if defined(__SOFT_FP__) __aeabi_f2lz(fp_t a) { #else __aeabi_f2lz(float a) { #endif return __fixsfdi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixsfsi.c ================================================ /* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" typedef si_int fixint_t; typedef su_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_f2iz(fp_t a) { return __fixsfsi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixunsdfdi.c ================================================ /* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunsdfdi(double a) { if (a <= 0.0) return 0; su_int high = a / 4294967296.f; /* a / 0x1p32f; */ su_int low = a - (double)high * 4294967296.f; /* high * 0x1p32f; */ return ((du_int)high << 32) | low; } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef du_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI du_int __fixunsdfdi(fp_t a) { return __fixuint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI du_int #if defined(__SOFT_FP__) __aeabi_d2ulz(fp_t a) { #else __aeabi_d2ulz(double a) { #endif return __fixunsdfdi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixunsdfsi.c ================================================ /* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" typedef su_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI su_int __fixunsdfsi(fp_t a) { return __fixuint(a); } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) { return __fixunsdfsi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixunssfdi.c ================================================ /* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunssfdi(float a) { if (a <= 0.0f) return 0; double da = a; su_int high = da / 4294967296.f; /* da / 0x1p32f; */ su_int low = da - (double)high * 4294967296.f; /* high * 0x1p32f; */ return ((du_int)high << 32) | low; } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef du_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI du_int __fixunssfdi(fp_t a) { return __fixuint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI du_int #if defined(__SOFT_FP__) __aeabi_f2ulz(fp_t a) { #else __aeabi_f2ulz(float a) { #endif return __fixunssfdi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fixunssfsi.c ================================================ /* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __fixunssfsi for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" typedef su_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI su_int __fixunssfsi(fp_t a) { return __fixuint(a); } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) { return __fixunssfsi(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/float.h ================================================ /*===---- float.h - Characteristics of floating point types ----------------=== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * *===-----------------------------------------------------------------------=== */ #ifndef __FLOAT_H #define __FLOAT_H /** * @file float.h */ /* Characteristics of floating point types, C99 5.2.4.2.2 */ #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ #define FLT_ROUNDS (__builtin_flt_rounds()) #define FLT_RADIX __FLT_RADIX__ #define FLT_MANT_DIG __FLT_MANT_DIG__ #define DBL_MANT_DIG __DBL_MANT_DIG__ #define LDBL_MANT_DIG __LDBL_MANT_DIG__ #if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) #define DECIMAL_DIG __DECIMAL_DIG__ #endif #define FLT_DIG __FLT_DIG__ #define DBL_DIG __DBL_DIG__ #define LDBL_DIG __LDBL_DIG__ #define FLT_MIN_EXP __FLT_MIN_EXP__ #define DBL_MIN_EXP __DBL_MIN_EXP__ #define LDBL_MIN_EXP __LDBL_MIN_EXP__ #define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ #define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ #define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ #define FLT_MAX_EXP __FLT_MAX_EXP__ #define DBL_MAX_EXP __DBL_MAX_EXP__ #define LDBL_MAX_EXP __LDBL_MAX_EXP__ #define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ #define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ #define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ #define FLT_MAX __FLT_MAX__ #define DBL_MAX __DBL_MAX__ #define LDBL_MAX __LDBL_MAX__ #define FLT_EPSILON __FLT_EPSILON__ #define DBL_EPSILON __DBL_EPSILON__ #define LDBL_EPSILON __LDBL_EPSILON__ #define FLT_MIN __FLT_MIN__ #define DBL_MIN __DBL_MIN__ #define LDBL_MIN __LDBL_MIN__ #define FLT_HAS_SUBNORM (-1) #define DBL_HAS_SUBNORM (-1) #define LDBL_HAS_SUBNORM (-1) #define DBL_FLT_HAS_SUBNORM (-1) #define LDBL_FLT_HAS_SUBNORM (-1) #if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) #define FLT_TRUE_MIN __FLT_DENORM_MIN__ #define DBL_TRUE_MIN __DBL_DENORM_MIN__ #define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ #define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__ #define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__ #define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__ #endif #endif /* __FLOAT_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/floatdidf.c ================================================ /*===-- floatdidf.c - Implement __floatdidf -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __floatdidf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: convert a to a double, rounding toward even. */ /* Assumption: double is a IEEE 64 bit floating point type * di_int is a 64 bit integral type */ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. */ COMPILER_RT_ABI double __floatdidf(di_int a) { static const double twop52 = 4503599627370496.0; // 0x1.0p52 static const double twop32 = 4294967296.0; // 0x1.0p32 union { int64_t x; double d; } low = { .d = twop52 }; const double high = (int32_t)(a >> 32) * twop32; low.x |= a & INT64_C(0x00000000ffffffff); const double result = (high - twop52) + low.d; return result; } #else /* Support for systems that don't have hardware floating-point; there are no flags to * set, and we don't want to code-gen to an unknown soft-float implementation. */ COMPILER_RT_ABI double __floatdidf(di_int a) { if (a == 0) return 0.0; const unsigned N = sizeof(di_int) * CHAR_BIT; const di_int s = a >> (N - 1); a = (a ^ s) - s; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > DBL_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit DBL_MANT_DIG-1 bits to the right of 1 * Q = bit DBL_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case DBL_MANT_DIG + 1: a <<= 1; break; case DBL_MANT_DIG + 2: break; default: a = ((du_int)a >> (sd - (DBL_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ if (a & ((du_int)1 << DBL_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to DBL_MANT_DIG bits */ } else { a <<= (DBL_MANT_DIG - sd); /* a is now rounded to DBL_MANT_DIG bits */ } double_bits fb; fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */ ((e + 1023) << 20) | /* exponent */ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ fb.u.s.low = (su_int)a; /* mantissa-low */ return fb.f; } #endif #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_l2d(di_int a) { return __floatdidf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatdisf.c ================================================ /*===-- floatdisf.c - Implement __floatdisf -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __floatdisf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ /* Returns: convert a to a float, rounding toward even.*/ /* Assumption: float is a IEEE 32 bit floating point type * di_int is a 64 bit integral type */ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" COMPILER_RT_ABI float __floatdisf(di_int a) { if (a == 0) return 0.0F; const unsigned N = sizeof(di_int) * CHAR_BIT; const di_int s = a >> (N - 1); a = (a ^ s) - s; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > FLT_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit FLT_MANT_DIG-1 bits to the right of 1 * Q = bit FLT_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case FLT_MANT_DIG + 1: a <<= 1; break; case FLT_MANT_DIG + 2: break; default: a = ((du_int)a >> (sd - (FLT_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ if (a & ((du_int)1 << FLT_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to FLT_MANT_DIG bits */ } else { a <<= (FLT_MANT_DIG - sd); /* a is now rounded to FLT_MANT_DIG bits */ } float_bits fb; fb.u = ((su_int)s & 0x80000000) | /* sign */ ((e + 127) << 23) | /* exponent */ ((su_int)a & 0x007FFFFF); /* mantissa */ return fb.f; } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_l2f(di_int a) { return __floatdisf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatsidf.c ================================================ //===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements integer to double-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatsidf(int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // All other cases begin by extracting the sign and absolute value of a rep_t sign = 0; if (a < 0) { sign = signBit; a = -a; } // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field and clear the implicit bit. Extra // cast to unsigned int is necessary to get the correct behavior for // the input INT_MIN. const int shift = significandBits - exponent; result = (rep_t)(unsigned int)a << shift ^ implicitBit; // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; // Insert the sign bit and return return fromRep(result | sign); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_i2d(int a) { return __floatsidf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatsisf.c ================================================ //===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements integer to single-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatsisf(int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // All other cases begin by extracting the sign and absolute value of a rep_t sign = 0; if (a < 0) { sign = signBit; a = -a; } // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field, rounding if it is a right-shift if (exponent <= significandBits) { const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; } else { const int shift = exponent - significandBits; result = (rep_t)a >> shift ^ implicitBit; rep_t round = (rep_t)a << (typeWidth - shift); if (round > signBit) result++; if (round == signBit) result += result & 1; } // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; // Insert the sign bit and return return fromRep(result | sign); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_i2f(int a) { return __floatsisf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatundidf.c ================================================ /* ===-- floatundidf.c - Implement __floatundidf ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __floatundidf for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ /* Returns: convert a to a double, rounding toward even. */ /* Assumption: double is a IEEE 64 bit floating point type * du_int is a 64 bit integral type */ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. */ COMPILER_RT_ABI double __floatundidf(du_int a) { static const double twop52 = 4503599627370496.0; // 0x1.0p52 static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84 static const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84 union { uint64_t x; double d; } high = { .d = twop84 }; union { uint64_t x; double d; } low = { .d = twop52 }; high.x |= a >> 32; low.x |= a & UINT64_C(0x00000000ffffffff); const double result = (high.d - twop84_plus_twop52) + low.d; return result; } #else /* Support for systems that don't have hardware floating-point; there are no flags to * set, and we don't want to code-gen to an unknown soft-float implementation. */ COMPILER_RT_ABI double __floatundidf(du_int a) { if (a == 0) return 0.0; const unsigned N = sizeof(du_int) * CHAR_BIT; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > DBL_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit DBL_MANT_DIG-1 bits to the right of 1 * Q = bit DBL_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case DBL_MANT_DIG + 1: a <<= 1; break; case DBL_MANT_DIG + 2: break; default: a = (a >> (sd - (DBL_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ if (a & ((du_int)1 << DBL_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to DBL_MANT_DIG bits */ } else { a <<= (DBL_MANT_DIG - sd); /* a is now rounded to DBL_MANT_DIG bits */ } double_bits fb; fb.u.s.high = ((e + 1023) << 20) | /* exponent */ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ fb.u.s.low = (su_int)a; /* mantissa-low */ return fb.f; } #endif #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_ul2d(du_int a) { return __floatundidf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatundisf.c ================================================ /*===-- floatundisf.c - Implement __floatundisf ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __floatundisf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ /* Returns: convert a to a float, rounding toward even. */ /* Assumption: float is a IEEE 32 bit floating point type * du_int is a 64 bit integral type */ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" COMPILER_RT_ABI float __floatundisf(du_int a) { if (a == 0) return 0.0F; const unsigned N = sizeof(du_int) * CHAR_BIT; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* 8 exponent */ if (sd > FLT_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit FLT_MANT_DIG-1 bits to the right of 1 * Q = bit FLT_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case FLT_MANT_DIG + 1: a <<= 1; break; case FLT_MANT_DIG + 2: break; default: a = (a >> (sd - (FLT_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ if (a & ((du_int)1 << FLT_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to FLT_MANT_DIG bits */ } else { a <<= (FLT_MANT_DIG - sd); /* a is now rounded to FLT_MANT_DIG bits */ } float_bits fb; fb.u = ((e + 127) << 23) | /* exponent */ ((su_int)a & 0x007FFFFF); /* mantissa */ return fb.f; } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_ul2f(du_int a) { return __floatundisf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatunsidf.c ================================================ //===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements unsigned integer to double-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatunsidf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field and clear the implicit bit. const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; return fromRep(result); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ui2d(unsigned int a) { return __floatunsidf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/floatunsisf.c ================================================ //===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements unsigned integer to single-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatunsisf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field, rounding if it is a right-shift if (exponent <= significandBits) { const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; } else { const int shift = exponent - significandBits; result = (rep_t)a >> shift ^ implicitBit; rep_t round = (rep_t)a << (typeWidth - shift); if (round > signBit) result++; if (round == signBit) result += result & 1; } // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; return fromRep(result); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_add_impl.inc ================================================ //===----- lib/fp_add_impl.inc - floaing point addition -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements soft-float addition with the IEEE-754 default rounding // (to nearest, ties to even). // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fp_t __addXf3__(fp_t a, fp_t b) { rep_t aRep = toRep(a); rep_t bRep = toRep(b); const rep_t aAbs = aRep & absMask; const rep_t bAbs = bRep & absMask; // Detect if a or b is zero, infinity, or NaN. if (aAbs - REP_C(1) >= infRep - REP_C(1) || bAbs - REP_C(1) >= infRep - REP_C(1)) { // NaN + anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything + NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // +/-infinity + -/+infinity = qNaN if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep); // +/-infinity + anything remaining = +/- infinity else return a; } // anything remaining + +/-infinity = +/-infinity if (bAbs == infRep) return b; // zero + anything = anything if (!aAbs) { // but we need to get the sign right for zero + zero if (!bAbs) return fromRep(toRep(a) & toRep(b)); else return b; } // anything + zero = anything if (!bAbs) return a; } // Swap a and b if necessary so that a has the larger absolute value. if (bAbs > aAbs) { const rep_t temp = aRep; aRep = bRep; bRep = temp; } // Extract the exponent and significand from the (possibly swapped) a and b. int aExponent = aRep >> significandBits & maxExponent; int bExponent = bRep >> significandBits & maxExponent; rep_t aSignificand = aRep & significandMask; rep_t bSignificand = bRep & significandMask; // Normalize any denormals, and adjust the exponent accordingly. if (aExponent == 0) aExponent = normalize(&aSignificand); if (bExponent == 0) bExponent = normalize(&bSignificand); // The sign of the result is the sign of the larger operand, a. If they // have opposite signs, we are performing a subtraction; otherwise addition. const rep_t resultSign = aRep & signBit; const bool subtraction = (aRep ^ bRep) & signBit; // Shift the significands to give us round, guard and sticky, and or in the // implicit significand bit. (If we fell through from the denormal path it // was already set by normalize( ), but setting it twice won't hurt // anything.) aSignificand = (aSignificand | implicitBit) << 3; bSignificand = (bSignificand | implicitBit) << 3; // Shift the significand of b by the difference in exponents, with a sticky // bottom bit to get rounding correct. const unsigned int align = aExponent - bExponent; if (align) { if (align < typeWidth) { const bool sticky = bSignificand << (typeWidth - align); bSignificand = bSignificand >> align | sticky; } else { bSignificand = 1; // sticky; b is known to be non-zero. } } if (subtraction) { aSignificand -= bSignificand; // If a == -b, return +zero. if (aSignificand == 0) return fromRep(0); // If partial cancellation occured, we need to left-shift the result // and adjust the exponent: if (aSignificand < implicitBit << 3) { const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); aSignificand <<= shift; aExponent -= shift; } } else /* addition */ { aSignificand += bSignificand; // If the addition carried up, we need to right-shift the result and // adjust the exponent: if (aSignificand & implicitBit << 4) { const bool sticky = aSignificand & 1; aSignificand = aSignificand >> 1 | sticky; aExponent += 1; } } // If we have overflowed the type, return +/- infinity: if (aExponent >= maxExponent) return fromRep(infRep | resultSign); if (aExponent <= 0) { // Result is denormal before rounding; the exponent is zero and we // need to shift the significand. const int shift = 1 - aExponent; const bool sticky = aSignificand << (typeWidth - shift); aSignificand = aSignificand >> shift | sticky; aExponent = 0; } // Low three bits are round, guard, and sticky. const int roundGuardSticky = aSignificand & 0x7; // Shift the significand into place, and mask off the implicit bit. rep_t result = aSignificand >> 3 & significandMask; // Insert the exponent and sign. result |= (rep_t)aExponent << significandBits; result |= resultSign; // Final rounding. The result may overflow to infinity, but that is the // correct result in that case. if (roundGuardSticky > 0x4) result++; if (roundGuardSticky == 0x4) result += result & 1; return fromRep(result); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_extend.h ================================================ //===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // Set source and destination setting // //===----------------------------------------------------------------------===// #ifndef FP_EXTEND_HEADER #define FP_EXTEND_HEADER #include "int_lib.h" #if defined SRC_SINGLE typedef float src_t; typedef uint32_t src_rep_t; #define SRC_REP_C UINT32_C static const int srcSigBits = 23; #define src_rep_t_clz __builtin_clz #elif defined SRC_DOUBLE typedef double src_t; typedef uint64_t src_rep_t; #define SRC_REP_C UINT64_C static const int srcSigBits = 52; static __inline int src_rep_t_clz(src_rep_t a) { #if defined __LP64__ return __builtin_clzl(a); #else if (a & REP_C(0xffffffff00000000)) return __builtin_clz(a >> 32); else return 32 + __builtin_clz(a & REP_C(0xffffffff)); #endif } #elif defined SRC_HALF typedef uint16_t src_t; typedef uint16_t src_rep_t; #define SRC_REP_C UINT16_C static const int srcSigBits = 10; #define src_rep_t_clz __builtin_clz #else #error Source should be half, single, or double precision! #endif // end source precision #if defined DST_SINGLE typedef float dst_t; typedef uint32_t dst_rep_t; #define DST_REP_C UINT32_C static const int dstSigBits = 23; #elif defined DST_DOUBLE typedef double dst_t; typedef uint64_t dst_rep_t; #define DST_REP_C UINT64_C static const int dstSigBits = 52; #elif defined DST_QUAD typedef long double dst_t; typedef __uint128_t dst_rep_t; #define DST_REP_C (__uint128_t) static const int dstSigBits = 112; #else #error Destination should be single, double, or quad precision! #endif // end destination precision // End of specialization parameters. Two helper routines for conversion to and // from the representation of floating-point data as integer values follow. static __inline src_rep_t srcToRep(src_t x) { const union { src_t f; src_rep_t i; } rep = { .f = x }; return rep.i; } static __inline dst_t dstFromRep(dst_rep_t x) { const union { dst_t f; dst_rep_t i; } rep = { .i = x }; return rep.f; } // End helper routines. Conversion implementation follows. #endif // FP_EXTEND_HEADER ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_extend_impl.inc ================================================ //=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a fairly generic conversion from a narrower to a wider // IEEE-754 floating-point type. The constants and types defined following the // includes below parameterize the conversion. // // It does not support types that don't use the usual IEEE-754 interchange // formats; specifically, some work would be needed to adapt it to // (for example) the Intel 80-bit format or PowerPC double-double format. // // Note please, however, that this implementation is only intended to support // *widening* operations; if you need to convert to a *narrower* floating-point // type (e.g. double -> float), then this routine will not do what you want it // to. // // It also requires that integer types at least as large as both formats // are available on the target platform; this may pose a problem when trying // to add support for quad on some 32-bit systems, for example. You also may // run into trouble finding an appropriate CLZ function for wide source types; // you will likely need to roll your own on some platforms. // // Finally, the following assumptions are made: // // 1. floating-point types and integer types have the same endianness on the // target platform // // 2. quiet NaNs, if supported, are indicated by the leading bit of the // significand field being set // //===----------------------------------------------------------------------===// #include "fp_extend.h" static __inline dst_t __extendXfYf2__(src_t a) { // Various constants whose values follow from the type parameters. // Any reasonable optimizer will fold and propagate all of these. const int srcBits = sizeof(src_t)*CHAR_BIT; const int srcExpBits = srcBits - srcSigBits - 1; const int srcInfExp = (1 << srcExpBits) - 1; const int srcExpBias = srcInfExp >> 1; const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); const src_rep_t srcAbsMask = srcSignMask - 1; const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); const src_rep_t srcNaNCode = srcQNaN - 1; const int dstBits = sizeof(dst_t)*CHAR_BIT; const int dstExpBits = dstBits - dstSigBits - 1; const int dstInfExp = (1 << dstExpBits) - 1; const int dstExpBias = dstInfExp >> 1; const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits; // Break a into a sign and representation of the absolute value const src_rep_t aRep = srcToRep(a); const src_rep_t aAbs = aRep & srcAbsMask; const src_rep_t sign = aRep & srcSignMask; dst_rep_t absResult; // If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted // to (signed) int. To avoid that, explicitly cast to src_rep_t. if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) { // a is a normal number. // Extend to the destination type by shifting the significand and // exponent into the proper position and rebiasing the exponent. absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits); absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits; } else if (aAbs >= srcInfinity) { // a is NaN or infinity. // Conjure the result by beginning with infinity, then setting the qNaN // bit (if needed) and right-aligning the rest of the trailing NaN // payload field. absResult = (dst_rep_t)dstInfExp << dstSigBits; absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits); absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits); } else if (aAbs) { // a is denormal. // renormalize the significand and clear the leading bit, then insert // the correct adjusted exponent in the destination type. const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal); absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale); absResult ^= dstMinNormal; const int resultExponent = dstExpBias - srcExpBias - scale + 1; absResult |= (dst_rep_t)resultExponent << dstSigBits; } else { // a is zero. absResult = 0; } // Apply the signbit to (dst_t)abs(a). const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits); return dstFromRep(result); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_fixint_impl.inc ================================================ //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements float to integer conversion for the // compiler-rt library. // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fixint_t __fixint(fp_t a) { const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2); const fixint_t fixint_min = -fixint_max - 1; // Break a into sign, exponent, significand const rep_t aRep = toRep(a); const rep_t aAbs = aRep & absMask; const fixint_t sign = aRep & signBit ? -1 : 1; const int exponent = (aAbs >> significandBits) - exponentBias; const rep_t significand = (aAbs & significandMask) | implicitBit; // If exponent is negative, the result is zero. if (exponent < 0) return 0; // If the value is too large for the integer type, saturate. if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT) return sign == 1 ? fixint_max : fixint_min; // If 0 <= exponent < significandBits, right shift to get the result. // Otherwise, shift left. if (exponent < significandBits) return sign * (significand >> (significandBits - exponent)); else return sign * ((fixint_t)significand << (exponent - significandBits)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_fixuint_impl.inc ================================================ //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements float to unsigned integer conversion for the // compiler-rt library. // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fixuint_t __fixuint(fp_t a) { // Break a into sign, exponent, significand const rep_t aRep = toRep(a); const rep_t aAbs = aRep & absMask; const int sign = aRep & signBit ? -1 : 1; const int exponent = (aAbs >> significandBits) - exponentBias; const rep_t significand = (aAbs & significandMask) | implicitBit; // If either the value or the exponent is negative, the result is zero. if (sign == -1 || exponent < 0) return 0; // If the value is too large for the integer type, saturate. if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT) return ~(fixuint_t)0; // If 0 <= exponent < significandBits, right shift to get the result. // Otherwise, shift left. if (exponent < significandBits) return significand >> (significandBits - exponent); else return (fixuint_t)significand << (exponent - significandBits); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_lib.h ================================================ //===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a configuration header for soft-float routines in compiler-rt. // This file does not provide any part of the compiler-rt interface, but defines // many useful constants and utility routines that are used in the // implementation of the soft-float routines in compiler-rt. // // Assumes that float, double and long double correspond to the IEEE-754 // binary32, binary64 and binary 128 types, respectively, and that integer // endianness matches floating point endianness on the target platform. // //===----------------------------------------------------------------------===// #ifndef FP_LIB_HEADER #define FP_LIB_HEADER #include #include #include #include "int_lib.h" // x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in // 32-bit mode. #if defined(__FreeBSD__) && defined(__i386__) #include #if __FreeBSD_version < 903000 // v9.3 #define uint64_t unsigned long long #define int64_t long long #undef UINT64_C #define UINT64_C(c) (c##ULL) #endif #endif #if defined SINGLE_PRECISION typedef uint32_t rep_t; typedef int32_t srep_t; typedef float fp_t; #define REP_C UINT32_C #define significandBits 23 static __inline int rep_clz(rep_t a) { return __builtin_clz(a); } // 32x32 --> 64 bit multiply static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { const uint64_t product = (uint64_t)a * b; *hi = product >> 32; *lo = product; } COMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b); #elif defined DOUBLE_PRECISION typedef uint64_t rep_t; typedef int64_t srep_t; typedef double fp_t; #define REP_C UINT64_C #define significandBits 52 static __inline int rep_clz(rep_t a) { #if defined __LP64__ return __builtin_clzl(a); #else if (a & REP_C(0xffffffff00000000)) return __builtin_clz(a >> 32); else return 32 + __builtin_clz(a & REP_C(0xffffffff)); #endif } #define loWord(a) (a & 0xffffffffU) #define hiWord(a) (a >> 32) // 64x64 -> 128 wide multiply for platforms that don't have such an operation; // many 64-bit platforms have this operation, but they tend to have hardware // floating-point, so we don't bother with a special case for them here. static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { // Each of the component 32x32 -> 64 products const uint64_t plolo = loWord(a) * loWord(b); const uint64_t plohi = loWord(a) * hiWord(b); const uint64_t philo = hiWord(a) * loWord(b); const uint64_t phihi = hiWord(a) * hiWord(b); // Sum terms that contribute to lo in a way that allows us to get the carry const uint64_t r0 = loWord(plolo); const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo); *lo = r0 + (r1 << 32); // Sum terms contributing to hi with the carry from lo *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi; } #undef loWord #undef hiWord COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b); #elif defined QUAD_PRECISION #if __LDBL_MANT_DIG__ == 113 #define CRT_LDBL_128BIT typedef __uint128_t rep_t; typedef __int128_t srep_t; typedef long double fp_t; #define REP_C (__uint128_t) // Note: Since there is no explicit way to tell compiler the constant is a // 128-bit integer, we let the constant be casted to 128-bit integer #define significandBits 112 static __inline int rep_clz(rep_t a) { const union { __uint128_t ll; #if _YUGA_BIG_ENDIAN struct { uint64_t high, low; } s; #else struct { uint64_t low, high; } s; #endif } uu = { .ll = a }; uint64_t word; uint64_t add; if (uu.s.high) { word = uu.s.high; add = 0; } else { word = uu.s.low; add = 64; } return __builtin_clzll(word) + add; } #define Word_LoMask UINT64_C(0x00000000ffffffff) #define Word_HiMask UINT64_C(0xffffffff00000000) #define Word_FullMask UINT64_C(0xffffffffffffffff) #define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask) #define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask) #define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask) #define Word_4(a) (uint64_t)(a & Word_LoMask) // 128x128 -> 256 wide multiply for platforms that don't have such an operation; // many 64-bit platforms have this operation, but they tend to have hardware // floating-point, so we don't bother with a special case for them here. static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { const uint64_t product11 = Word_1(a) * Word_1(b); const uint64_t product12 = Word_1(a) * Word_2(b); const uint64_t product13 = Word_1(a) * Word_3(b); const uint64_t product14 = Word_1(a) * Word_4(b); const uint64_t product21 = Word_2(a) * Word_1(b); const uint64_t product22 = Word_2(a) * Word_2(b); const uint64_t product23 = Word_2(a) * Word_3(b); const uint64_t product24 = Word_2(a) * Word_4(b); const uint64_t product31 = Word_3(a) * Word_1(b); const uint64_t product32 = Word_3(a) * Word_2(b); const uint64_t product33 = Word_3(a) * Word_3(b); const uint64_t product34 = Word_3(a) * Word_4(b); const uint64_t product41 = Word_4(a) * Word_1(b); const uint64_t product42 = Word_4(a) * Word_2(b); const uint64_t product43 = Word_4(a) * Word_3(b); const uint64_t product44 = Word_4(a) * Word_4(b); const __uint128_t sum0 = (__uint128_t)product44; const __uint128_t sum1 = (__uint128_t)product34 + (__uint128_t)product43; const __uint128_t sum2 = (__uint128_t)product24 + (__uint128_t)product33 + (__uint128_t)product42; const __uint128_t sum3 = (__uint128_t)product14 + (__uint128_t)product23 + (__uint128_t)product32 + (__uint128_t)product41; const __uint128_t sum4 = (__uint128_t)product13 + (__uint128_t)product22 + (__uint128_t)product31; const __uint128_t sum5 = (__uint128_t)product12 + (__uint128_t)product21; const __uint128_t sum6 = (__uint128_t)product11; const __uint128_t r0 = (sum0 & Word_FullMask) + ((sum1 & Word_LoMask) << 32); const __uint128_t r1 = (sum0 >> 64) + ((sum1 >> 32) & Word_FullMask) + (sum2 & Word_FullMask) + ((sum3 << 32) & Word_HiMask); *lo = r0 + (r1 << 64); *hi = (r1 >> 64) + (sum1 >> 96) + (sum2 >> 64) + (sum3 >> 32) + sum4 + (sum5 << 32) + (sum6 << 64); } #undef Word_1 #undef Word_2 #undef Word_3 #undef Word_4 #undef Word_HiMask #undef Word_LoMask #undef Word_FullMask #endif // __LDBL_MANT_DIG__ == 113 #else #error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined. #endif #if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || defined(CRT_LDBL_128BIT) #define typeWidth (sizeof(rep_t) * CHAR_BIT) #define exponentBits (typeWidth - significandBits - 1) #define maxExponent ((1 << exponentBits) - 1) #define exponentBias (maxExponent >> 1) #define implicitBit (REP_C(1) << significandBits) #define significandMask (implicitBit - 1U) #define signBit (REP_C(1) << (significandBits + exponentBits)) #define absMask (signBit - 1U) #define exponentMask (absMask ^ significandMask) #define oneRep ((rep_t)exponentBias << significandBits) #define infRep exponentMask #define quietBit (implicitBit >> 1) #define qnanRep (exponentMask | quietBit) static __inline rep_t toRep(fp_t x) { const union { fp_t f; rep_t i; } rep = { .f = x }; return rep.i; } static __inline fp_t fromRep(rep_t x) { const union { fp_t f; rep_t i; } rep = { .i = x }; return rep.f; } static __inline int normalize(rep_t *significand) { const int shift = rep_clz(*significand) - rep_clz(implicitBit); *significand <<= shift; return 1 - shift; } static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) { *hi = *hi << count | *lo >> (typeWidth - count); *lo = *lo << count; } static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) { if (count < typeWidth) { const bool sticky = *lo << (typeWidth - count); *lo = *hi << (typeWidth - count) | *lo >> count | sticky; *hi = *hi >> count; } else if (count < 2 * typeWidth) { const bool sticky = *hi << (2 * typeWidth - count) | *lo; *lo = *hi >> (count - typeWidth) | sticky; *hi = 0; } else { const bool sticky = *hi | *lo; *lo = sticky; *hi = 0; } } #endif #endif // FP_LIB_HEADER ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_mul_impl.inc ================================================ //===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements soft-float multiplication with the IEEE-754 default // rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fp_t __mulXf3__(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN * anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything * NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity * non-zero = +/- infinity if (bAbs) return fromRep(aAbs | productSign); // infinity * zero = NaN else return fromRep(qnanRep); } if (bAbs == infRep) { //? non-zero * infinity = +/- infinity if (aAbs) return fromRep(bAbs | productSign); // zero * infinity = NaN else return fromRep(qnanRep); } // zero * anything = +/- zero if (!aAbs) return fromRep(productSign); // anything * zero = +/- zero if (!bAbs) return fromRep(productSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale += normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; // Get the significand of a*b. Before multiplying the significands, shift // one of them left to left-align it in the field. Thus, the product will // have (exponentBits + 2) integral digits, all but two of which must be // zero. Normalizing this result is just a conditional left-shift by one // and bumping the exponent accordingly. rep_t productHi, productLo; wideMultiply(aSignificand, bSignificand << exponentBits, &productHi, &productLo); int productExponent = aExponent + bExponent - exponentBias + scale; // Normalize the significand, adjust exponent if needed. if (productHi & implicitBit) productExponent++; else wideLeftShift(&productHi, &productLo, 1); // If we have overflowed the type, return +/- infinity. if (productExponent >= maxExponent) return fromRep(infRep | productSign); if (productExponent <= 0) { // Result is denormal before rounding // // If the result is so small that it just underflows to zero, return // a zero of the appropriate sign. Mathematically there is no need to // handle this case separately, but we make it a special case to // simplify the shift logic. const unsigned int shift = REP_C(1) - (unsigned int)productExponent; if (shift >= typeWidth) return fromRep(productSign); // Otherwise, shift the significand of the result so that the round // bit is the high bit of productLo. wideRightShiftWithSticky(&productHi, &productLo, shift); } else { // Result is normal before rounding; insert the exponent. productHi &= significandMask; productHi |= (rep_t)productExponent << significandBits; } // Insert the sign of the result: productHi |= productSign; // Final rounding. The final result may overflow to infinity, or underflow // to zero, but those are the correct results in those cases. We use the // default IEEE-754 round-to-nearest, ties-to-even rounding mode. if (productLo > signBit) productHi++; if (productLo == signBit) productHi += productHi & 1; return fromRep(productHi); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_trunc.h ================================================ //=== lib/fp_trunc.h - high precision -> low precision conversion *- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // Set source and destination precision setting // //===----------------------------------------------------------------------===// #ifndef FP_TRUNC_HEADER #define FP_TRUNC_HEADER #include "int_lib.h" #if defined SRC_SINGLE typedef float src_t; typedef uint32_t src_rep_t; #define SRC_REP_C UINT32_C static const int srcSigBits = 23; #elif defined SRC_DOUBLE typedef double src_t; typedef uint64_t src_rep_t; #define SRC_REP_C UINT64_C static const int srcSigBits = 52; #elif defined SRC_QUAD typedef long double src_t; typedef __uint128_t src_rep_t; #define SRC_REP_C (__uint128_t) static const int srcSigBits = 112; #else #error Source should be double precision or quad precision! #endif // end source precision #if defined DST_DOUBLE typedef double dst_t; typedef uint64_t dst_rep_t; #define DST_REP_C UINT64_C static const int dstSigBits = 52; #elif defined DST_SINGLE typedef float dst_t; typedef uint32_t dst_rep_t; #define DST_REP_C UINT32_C static const int dstSigBits = 23; #elif defined DST_HALF typedef uint16_t dst_t; typedef uint16_t dst_rep_t; #define DST_REP_C UINT16_C static const int dstSigBits = 10; #else #error Destination should be single precision or double precision! #endif // end destination precision // End of specialization parameters. Two helper routines for conversion to and // from the representation of floating-point data as integer values follow. static __inline src_rep_t srcToRep(src_t x) { const union { src_t f; src_rep_t i; } rep = { .f = x }; return rep.i; } static __inline dst_t dstFromRep(dst_rep_t x) { const union { dst_t f; dst_rep_t i; } rep = { .i = x }; return rep.f; } #endif // FP_TRUNC_HEADER ================================================ FILE: golang/uPIMulator/sdk/syslib/fp_trunc_impl.inc ================================================ //= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a fairly generic conversion from a wider to a narrower // IEEE-754 floating-point type in the default (round to nearest, ties to even) // rounding mode. The constants and types defined following the includes below // parameterize the conversion. // // This routine can be trivially adapted to support conversions to // half-precision or from quad-precision. It does not support types that don't // use the usual IEEE-754 interchange formats; specifically, some work would be // needed to adapt it to (for example) the Intel 80-bit format or PowerPC // double-double format. // // Note please, however, that this implementation is only intended to support // *narrowing* operations; if you need to convert to a *wider* floating-point // type (e.g. float -> double), then this routine will not do what you want it // to. // // It also requires that integer types at least as large as both formats // are available on the target platform; this may pose a problem when trying // to add support for quad on some 32-bit systems, for example. // // Finally, the following assumptions are made: // // 1. floating-point types and integer types have the same endianness on the // target platform // // 2. quiet NaNs, if supported, are indicated by the leading bit of the // significand field being set // //===----------------------------------------------------------------------===// #include "fp_trunc.h" static __inline dst_t __truncXfYf2__(src_t a) { // Various constants whose values follow from the type parameters. // Any reasonable optimizer will fold and propagate all of these. const int srcBits = sizeof(src_t)*CHAR_BIT; const int srcExpBits = srcBits - srcSigBits - 1; const int srcInfExp = (1 << srcExpBits) - 1; const int srcExpBias = srcInfExp >> 1; const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; const src_rep_t srcSignificandMask = srcMinNormal - 1; const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); const src_rep_t srcAbsMask = srcSignMask - 1; const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1; const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1); const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); const src_rep_t srcNaNCode = srcQNaN - 1; const int dstBits = sizeof(dst_t)*CHAR_BIT; const int dstExpBits = dstBits - dstSigBits - 1; const int dstInfExp = (1 << dstExpBits) - 1; const int dstExpBias = dstInfExp >> 1; const int underflowExponent = srcExpBias + 1 - dstExpBias; const int overflowExponent = srcExpBias + dstInfExp - dstExpBias; const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits; const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits; const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1); const dst_rep_t dstNaNCode = dstQNaN - 1; // Break a into a sign and representation of the absolute value const src_rep_t aRep = srcToRep(a); const src_rep_t aAbs = aRep & srcAbsMask; const src_rep_t sign = aRep & srcSignMask; dst_rep_t absResult; if (aAbs - underflow < aAbs - overflow) { // The exponent of a is within the range of normal numbers in the // destination format. We can convert by simply right-shifting with // rounding and adjusting the exponent. absResult = aAbs >> (srcSigBits - dstSigBits); absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits; const src_rep_t roundBits = aAbs & roundMask; // Round to nearest if (roundBits > halfway) absResult++; // Ties to even else if (roundBits == halfway) absResult += absResult & 1; } else if (aAbs > srcInfinity) { // a is NaN. // Conjure the result by beginning with infinity, setting the qNaN // bit and inserting the (truncated) trailing NaN field. absResult = (dst_rep_t)dstInfExp << dstSigBits; absResult |= dstQNaN; absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode; } else if (aAbs >= overflow) { // a overflows to infinity. absResult = (dst_rep_t)dstInfExp << dstSigBits; } else { // a underflows on conversion to the destination type or is an exact // zero. The result may be a denormal or zero. Extract the exponent // to get the shift amount for the denormalization. const int aExp = aAbs >> srcSigBits; const int shift = srcExpBias - dstExpBias - aExp + 1; const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal; // Right shift by the denormalization amount with sticky. if (shift > srcSigBits) { absResult = 0; } else { const bool sticky = significand << (srcBits - shift); src_rep_t denormalizedSignificand = significand >> shift | sticky; absResult = denormalizedSignificand >> (srcSigBits - dstSigBits); const src_rep_t roundBits = denormalizedSignificand & roundMask; // Round to nearest if (roundBits > halfway) absResult++; // Ties to even else if (roundBits == halfway) absResult += absResult & 1; } } // Apply the signbit to (dst_t)abs(a). const dst_rep_t result = absResult | sign >> (srcBits - dstBits); return dstFromRep(result); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fsb_allocator.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include ATOMIC_BIT_INIT(__fsb_lock); // noinline, because part of grind tracked functions fsb_allocator_t __noinline fsb_alloc(unsigned int block_size, unsigned int nb_of_blocks) { if (block_size > 0xFFFFFFF8) { __asm__ volatile("fault " __STR(__FAULT_ALLOC_HEAP_FULL__)); unreachable(); } block_size = (block_size == 0) ? 8 : (block_size + 7) & ~7; unsigned int memory_space_to_allocate = block_size * nb_of_blocks + 4; void *memory = mem_alloc(memory_space_to_allocate); unsigned int first_block = (unsigned int)memory; for (unsigned int each_block = 0; each_block < nb_of_blocks - 1; ++each_block) { unsigned int next_block_address = (unsigned int)(memory + block_size); *((unsigned int *)memory) = next_block_address; memory = (void *)next_block_address; } *((unsigned int *)memory) = 0; memory += block_size; void *free_ptr = memory; *((unsigned int *)free_ptr) = first_block; return (fsb_allocator_t)free_ptr; } // noinline, because part of grind tracked functions void *__noinline fsb_get(fsb_allocator_t allocator) { void **result; ATOMIC_BIT_ACQUIRE(__fsb_lock); __asm__ volatile("lw %[res], %[alloc], 0" : [res] "=r"(result) : [alloc] "r"(allocator)); if (result == NULL) { ATOMIC_BIT_RELEASE(__fsb_lock); return NULL; } void *next = *result; __asm__ volatile("sw %[alloc], 0, %[res]" : : [res] "r"(next), [alloc] "r"(allocator)); ATOMIC_BIT_RELEASE(__fsb_lock); return (void *)result; } // noinline, because part of grind tracked functions void __noinline fsb_free(fsb_allocator_t allocator, void *ptr) { void *next_free; ATOMIC_BIT_ACQUIRE(__fsb_lock); __asm__ volatile("lw %[res], %[alloc], 0" : [res] "=r"(next_free) : [alloc] "r"(allocator)); *((void **)ptr) = next_free; __asm__ volatile("sw %[alloc], 0, %[res]" : : [res] "r"(ptr), [alloc] "r"(allocator)); ATOMIC_BIT_RELEASE(__fsb_lock); } ================================================ FILE: golang/uPIMulator/sdk/syslib/fsb_allocator.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_FBS_ALLOC_H #define DPUSYSCORE_FBS_ALLOC_H /** * @file fsb_allocator.h * @brief Provides a fixed-size block memory allocator. * * @internal When defining an allocator, the total memory needed will be allocated, using mem_alloc. * The allocator structure is a pointer to the next available block. In each free block, the first four bytes * store a pointer to the following free block, creating a linked list. To allocate a block, we just check * the free pointer, check the next free pointer and update the free pointer accordingly. To free a block, we * just check the free pointer, update it with the newly free block, and update the next pointer of this block * with the previous free pointer. * There is no protection to prevent invalid block to be added to the list. Moreover, the list being in the free * blocks, if there is some memory overflow from a block, the list might be corrupted and totally invalid. */ /** * @fn fsb_allocator_t * @brief A fixed-size block allocator. */ typedef void **fsb_allocator_t; /** * @fn fsb_alloc * @brief Allocate and initialize a fixed-size block allocator. * * @param block_size the size of the blocks allocated (will be realigned on 8 bytes, with a minimum of 8 bytes) * @param nb_of_blocks the number of blocks allocated * @throws a fault if there is no memory left * @return The newly allocated and ready-to-use fixed-size block allocator. */ fsb_allocator_t fsb_alloc(unsigned int block_size, unsigned int nb_of_blocks); /** * @fn fsb_get * @brief Own a block of the specified fixed-size block allocator, in a runtime-safe way. * * @param allocator the allocator from which we take the block * @return A pointer to the owned block if one was available, NULL otherwise. */ void * fsb_get(fsb_allocator_t allocator); /** * @fn fsb_free * @brief Free a block of the specified fixed-size block allocator, in a runtime-safe way. * * @param allocator the allocator in which we put the block back in * @param ptr the pointer to the block to free */ void fsb_free(fsb_allocator_t allocator, void *ptr); #endif /* DPUSYSCORE_FBS_ALLOC_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/handshake.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include unsigned char __handshake_array[NR_THREADS] = { [0 ...(NR_THREADS - 1)] = __EMPTY_WAIT_QUEUE }; ATOMIC_BIT_INIT(__handshake)[NR_THREADS]; #define __acquire_handshake(off) __ATOMIC_BIT_ACQUIRE(off + (ATOMIC_BIT_GET(__handshake) - &__atomic_start_addr), 0) #define __release_handshake(off) __ATOMIC_BIT_RELEASE(off + (ATOMIC_BIT_GET(__handshake) - &__atomic_start_addr), 0) void handshake_notify(void) { thread_id_t tid = me(); unsigned char info; __acquire_handshake(tid); info = __handshake_array[tid]; if (unlikely(info == __EMPTY_WAIT_QUEUE)) { __handshake_array[tid] = tid; __release_handshake(tid); __stop(); } else { __resume(info, "0"); __handshake_array[tid] = __EMPTY_WAIT_QUEUE; __release_handshake(tid); } } int handshake_wait_for(unsigned int notifier) { thread_id_t tid = me(); unsigned char thread = (unsigned char)notifier; __acquire_handshake(thread); unsigned char info = __handshake_array[thread]; if (unlikely(info == __EMPTY_WAIT_QUEUE)) { __handshake_array[thread] = tid; __release_handshake(thread); __stop(); } else { if (unlikely(info != thread)) { errno = EALREADY; __release_handshake(thread); return EALREADY; } else { __resume(info, "0"); __handshake_array[thread] = __EMPTY_WAIT_QUEUE; } __release_handshake(thread); } return 0; } ================================================ FILE: golang/uPIMulator/sdk/syslib/handshake.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_HANDSHAKE_H #define DPUSYSCORE_HANDSHAKE_H /** * @file handshake.h * @brief Synchronization with handshakes. * * This synchronization mechanism allows to synchronize 2 tasklets. One tasklet will serve as a notifier * and will call handshake_notify() and the other as a customer and will call handshake_wait_for(notifier). * * @internal If the notifier called handshake_notify() before the customer, it will stop until some tasklet * calls handshake_wait_for(notifier). * If a tasklet called handshake_wait_for(notifier) before the notifier, it will stop until * the notifier calls handshake_notify(). If afterwards (still before the notifier calls * handshake_notify()) another tasklet attempts to call handshake_wait_for(notifier) with * the same tasklet in the parameter, the function will do nothing and will return the number * of error and set the errno to the corresponding error number. */ #include /** * @fn handshake_notify * @brief Notifies a tasklet waiting for the notifier. * * The invoking tasklet is suspended until another tasklet calls handshake_wait_for(notifier). * When this condition is reached, the function resumes the waiting tasklet. */ void handshake_notify(void); /** * @fn handshake_wait_for * @brief Waits for the notifier tasklet * * The invoking tasklet is suspended until the notifier tasklet (indicated in the parameter) sends a * notification to tell the invoking tasklet that it can go ahead. * * Beware that if the notifier tasklet and the invoking tasklet are the same, the tasklet will be suspended with no * easy way to wake it up. The user should check this case itself if it is something that their program allows. * * If the number of the notifier is not a defined tasklet, the function behavior is undefined. If some other tasklet has * already called handshake_wait_for() with the same notifier in the parameter and that the notifier has not yet called * handshake_notify(), the function will do nothing and simply return EALREADY. * * In both cases the errno will be set to the corresponding error number. * * @param notifier a number to wait the notification from. It must be a defined tasklet. * @return 0 if no error was detected, EALREADY if a corresponding error was detected. */ int handshake_wait_for(sysname_t notifier); #endif /* DPUSYSCORE_HANDSHAKE_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/int_endianness.h ================================================ /* ===-- int_endianness.h - configuration header for compiler-rt ------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== */ #ifndef INT_ENDIANNESS_H #define INT_ENDIANNESS_H #if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) /* Clang and GCC provide built-in endianness definitions. */ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* __BYTE_ORDER__ */ #else /* Compilers other than Clang or GCC. */ #if defined(__SVR4) && defined(__sun) #include #if defined(_BIG_ENDIAN) #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif defined(_LITTLE_ENDIAN) #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #else /* !_LITTLE_ENDIAN */ #error "unknown endianness" #endif /* !_LITTLE_ENDIAN */ #endif /* Solaris and AuroraUX. */ /* .. */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__minix) #include #if _BYTE_ORDER == _BIG_ENDIAN #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif _BYTE_ORDER == _LITTLE_ENDIAN #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* _BYTE_ORDER */ #endif /* *BSD */ #if defined(__OpenBSD__) || defined(__Bitrig__) #include #if _BYTE_ORDER == _BIG_ENDIAN #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif _BYTE_ORDER == _LITTLE_ENDIAN #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* _BYTE_ORDER */ #endif /* OpenBSD and Bitrig. */ /* .. */ /* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the * compiler (at least with GCC) */ #if defined(__APPLE__) || defined(__ellcc__) #ifdef __BIG_ENDIAN__ #if __BIG_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #endif #endif /* __BIG_ENDIAN__ */ #ifdef __LITTLE_ENDIAN__ #if __LITTLE_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif #endif /* __LITTLE_ENDIAN__ */ #endif /* Mac OSX */ /* .. */ #if defined(_WIN32) #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* Windows */ #endif /* Clang or GCC. */ /* . */ #if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN) #error Unable to determine endian #endif /* Check we found an endianness correctly. */ #endif /* INT_ENDIANNESS_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/int_lib.h ================================================ /* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== */ #ifndef INT_LIB_H #define INT_LIB_H /* Assumption: Signed integral is 2's complement. */ /* Assumption: Right shift of signed negative is arithmetic shift. */ /* Assumption: Endianness is little or big (not mixed). */ #if defined(__ELF__) #define FNALIAS(alias_name, original_name) void alias_name() __attribute__((alias(#original_name))) #else #define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")") #endif /* ABI macro definitions */ #if __ARM_EABI__ #ifdef COMPILER_RT_ARMHF_TARGET #define COMPILER_RT_ABI #else #define COMPILER_RT_ABI __attribute__((__pcs__("aapcs"))) #endif #else #define COMPILER_RT_ABI #endif #define AEABI_RTABI __attribute__((__pcs__("aapcs"))) #ifdef _MSC_VER #define ALWAYS_INLINE __forceinline #define NOINLINE __declspec(noinline) #define NORETURN __declspec(noreturn) #define UNUSED #else #define ALWAYS_INLINE __attribute__((always_inline)) #define NOINLINE __attribute__((noinline)) #define NORETURN __attribute__((noreturn)) #define UNUSED __attribute__((unused)) #endif #if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE)) /* * Kernel and boot environment can't use normal headers, * so use the equivalent system headers. */ #include #include #include #else /* Include the standard compiler builtin headers we use functionality from. */ #include #include #include #include #endif /* Include the commonly used internal type definitions. */ #include "int_types.h" /* Include internal utility function declarations. */ #include "int_util.h" COMPILER_RT_ABI si_int __paritysi2(si_int a); COMPILER_RT_ABI si_int __paritydi2(di_int a); COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem); COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem); #ifdef CRT_HAS_128BIT COMPILER_RT_ABI si_int __clzti2(ti_int a); COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); #endif /* Definitions for builtins unavailable on MSVC */ #if defined(_MSC_VER) && !defined(__clang__) #include uint32_t __inline __builtin_ctz(uint32_t value) { unsigned long trailing_zero = 0; if (_BitScanForward(&trailing_zero, value)) return trailing_zero; return 32; } uint32_t __inline __builtin_clz(uint32_t value) { unsigned long leading_zero = 0; if (_BitScanReverse(&leading_zero, value)) return 31 - leading_zero; return 32; } #if defined(_M_ARM) || defined(_M_X64) uint32_t __inline __builtin_clzll(uint64_t value) { unsigned long leading_zero = 0; if (_BitScanReverse64(&leading_zero, value)) return 63 - leading_zero; return 64; } #else uint32_t __inline __builtin_clzll(uint64_t value) { if (value == 0) return 64; uint32_t msh = (uint32_t)(value >> 32); uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF); if (msh != 0) return __builtin_clz(msh); return 32 + __builtin_clz(lsh); } #endif #define __builtin_clzl __builtin_clzll #endif /* defined(_MSC_VER) && !defined(__clang__) */ #endif /* INT_LIB_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/int_math.h ================================================ /* ===-- int_math.h - internal math inlines ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===-----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines substitutes for the libm functions used in some of the * compiler-rt implementations, defined in such a way that there is not a direct * dependency on libm or math.h. Instead, we use the compiler builtin versions * where available. This reduces our dependencies on the system SDK by foisting * the responsibility onto the compiler. * * ===-----------------------------------------------------------------------=== */ #ifndef INT_MATH_H #define INT_MATH_H #ifndef __has_builtin #define __has_builtin(x) 0 #endif #if defined(_MSC_VER) && !defined(__clang__) #include #include #include #endif #if defined(_MSC_VER) && !defined(__clang__) #define CRT_INFINITY INFINITY #else #define CRT_INFINITY __builtin_huge_valf() #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_isfinite(x) _finite((x)) #define crt_isinf(x) !_finite((x)) #define crt_isnan(x) _isnan((x)) #else /* Define crt_isfinite in terms of the builtin if available, otherwise provide * an alternate version in terms of our other functions. This supports some * versions of GCC which didn't have __builtin_isfinite. */ #if __has_builtin(__builtin_isfinite) #define crt_isfinite(x) __builtin_isfinite((x)) #elif defined(__GNUC__) #define crt_isfinite(x) \ __extension__(({ \ __typeof((x)) x_ = (x); \ crt_isinf(x_) && crt_isnan(x_); \ })) #else #error "Do not know how to check for infinity" #endif /* __has_builtin(__builtin_isfinite) */ #define crt_isinf(x) __builtin_isinf((x)) #define crt_isnan(x) __builtin_isnan((x)) #endif /* _MSC_VER */ #if defined(_MSC_VER) && !defined(__clang__) #define crt_copysign(x, y) copysign((x), (y)) #define crt_copysignf(x, y) copysignf((x), (y)) #define crt_copysignl(x, y) copysignl((x), (y)) #else #define crt_copysign(x, y) __builtin_copysign((x), (y)) #define crt_copysignf(x, y) __builtin_copysignf((x), (y)) #define crt_copysignl(x, y) __builtin_copysignl((x), (y)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_fabs(x) fabs((x)) #define crt_fabsf(x) fabsf((x)) #define crt_fabsl(x) fabs((x)) #else #define crt_fabs(x) __builtin_fabs((x)) #define crt_fabsf(x) __builtin_fabsf((x)) #define crt_fabsl(x) __builtin_fabsl((x)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_fmax(x, y) __max((x), (y)) #define crt_fmaxf(x, y) __max((x), (y)) #define crt_fmaxl(x, y) __max((x), (y)) #else #define crt_fmax(x, y) __builtin_fmax((x), (y)) #define crt_fmaxf(x, y) __builtin_fmaxf((x), (y)) #define crt_fmaxl(x, y) __builtin_fmaxl((x), (y)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_logb(x) logb((x)) #define crt_logbf(x) logbf((x)) #define crt_logbl(x) logbl((x)) #else #define crt_logb(x) __builtin_logb((x)) #define crt_logbf(x) __builtin_logbf((x)) #define crt_logbl(x) __builtin_logbl((x)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_scalbn(x, y) scalbn((x), (y)) #define crt_scalbnf(x, y) scalbnf((x), (y)) #define crt_scalbnl(x, y) scalbnl((x), (y)) #else #define crt_scalbn(x, y) __builtin_scalbn((x), (y)) #define crt_scalbnf(x, y) __builtin_scalbnf((x), (y)) #define crt_scalbnl(x, y) __builtin_scalbnl((x), (y)) #endif #endif /* INT_MATH_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/int_types.h ================================================ /* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines various standard types, most importantly a number of unions * used to access parts of larger types. * * ===----------------------------------------------------------------------=== */ #ifndef INT_TYPES_H #define INT_TYPES_H #include "int_endianness.h" /* si_int is defined in Linux sysroot's asm-generic/siginfo.h */ #ifdef si_int #undef si_int #endif typedef int si_int; typedef unsigned su_int; typedef long long di_int; typedef unsigned long long du_int; typedef union { di_int all; struct { #if _YUGA_LITTLE_ENDIAN su_int low; si_int high; #else si_int high; su_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } dwords; typedef union { du_int all; struct { #if _YUGA_LITTLE_ENDIAN su_int low; su_int high; #else su_int high; su_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } udwords; #if (defined(__LP64__) || defined(__wasm__) || defined(__mips64)) #define CRT_HAS_128BIT #endif #ifdef CRT_HAS_128BIT typedef int ti_int __attribute__((mode(TI))); typedef unsigned tu_int __attribute__((mode(TI))); typedef union { ti_int all; struct { #if _YUGA_LITTLE_ENDIAN du_int low; di_int high; #else di_int high; du_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } twords; typedef union { tu_int all; struct { #if _YUGA_LITTLE_ENDIAN du_int low; du_int high; #else du_int high; du_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } utwords; static __inline ti_int make_ti(di_int h, di_int l) { twords r; r.s.high = h; r.s.low = l; return r.all; } static __inline tu_int make_tu(du_int h, du_int l) { utwords r; r.s.high = h; r.s.low = l; return r.all; } #endif /* CRT_HAS_128BIT */ typedef union { su_int u; float f; } float_bits; typedef union { udwords u; double f; } double_bits; typedef struct { #if _YUGA_LITTLE_ENDIAN udwords low; udwords high; #else udwords high; udwords low; #endif /* _YUGA_LITTLE_ENDIAN */ } uqwords; typedef union { uqwords u; long double f; } long_double_bits; #if __STDC_VERSION__ >= 199901L typedef float _Complex Fcomplex; typedef double _Complex Dcomplex; typedef long double _Complex Lcomplex; #define COMPLEX_REAL(x) __real__(x) #define COMPLEX_IMAGINARY(x) __imag__(x) #else typedef struct { float real, imaginary; } Fcomplex; typedef struct { double real, imaginary; } Dcomplex; typedef struct { long double real, imaginary; } Lcomplex; #define COMPLEX_REAL(x) (x).real #define COMPLEX_IMAGINARY(x) (x).imaginary #endif #endif /* INT_TYPES_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/int_util.c ================================================ /* ===-- int_util.c - Implement internal utilities --------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #include "int_util.h" /* NOTE: The definitions in this file are declared weak because we clients to be * able to arbitrarily package individual functions into separate .a files. If * we did not declare these weak, some link situations might end up seeing * duplicate strong definitions of the same symbol. * * We can't use this solution for kernel use (which may not support weak), but * currently expect that when built for kernel use all the functionality is * packaged into a single library. */ #ifdef KERNEL_USE NORETURN extern void panic(const char *, ...); #ifndef _WIN32 __attribute__((visibility("hidden"))) #endif void compilerrt_abort_impl(const char *file, int line, const char *function) { panic("%s:%d: abort in %s", file, line, function); } #elif __APPLE__ /* from libSystem.dylib */ NORETURN extern void __assert_rtn(const char *func, const char *file, int line, const char *message); #ifndef _WIN32 __attribute__((weak)) __attribute__((visibility("hidden"))) #endif void compilerrt_abort_impl(const char *file, int line, const char *function) { __assert_rtn(function, file, line, "libcompiler_rt abort"); } #else /* Get the system definition of abort() */ #include #ifndef _WIN32 // JFR dirty patch // DPUCC doesn't like it either __attribute__((weak)) // DPUCC doesn't like it either __attribute__((visibility("hidden"))) // End of patch #endif void compilerrt_abort_impl(const char *file __attribute__((unused)), int line __attribute__((unused)), const char *function __attribute__((unused))) { abort(); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/int_util.h ================================================ /* ===-- int_util.h - internal utility functions ----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===-----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines non-inline utilities which are available for use in the * library. The function definitions themselves are all contained in int_util.c * which will always be compiled into any compiler-rt library. * * ===-----------------------------------------------------------------------=== */ #ifndef INT_UTIL_H #define INT_UTIL_H /** \brief Trigger a program abort (or panic for kernel code). */ #define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, __func__) NORETURN void compilerrt_abort_impl(const char *file, int line, const char *function); #define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__) #define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt) #define COMPILE_TIME_ASSERT2(expr, cnt) typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED #endif /* INT_UTIL_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/listener.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include extern bool fetch_request(uint32_t fifo_info, uint32_t *request, uint32_t request_size); extern bool fifo_is_full(uint32_t fifo_info, uint32_t request_size); extern void fifo_produce(uint32_t fifo_info, uint32_t *request, uint32_t request_size); static inline uint32_t fifo_sys_fetch_info(uint32_t fid) { extern uint32_t __sys_fifo_sys_table; return (&__sys_fifo_sys_table)[fid]; } static inline uint32_t fifo_fetch_info(sysname_t recipient) { extern uint32_t __sys_fifo_table_ptr; return *((uint32_t *)((&__sys_fifo_table_ptr)[recipient] & 0xFFFF)); } static inline sysname_t fetch_recipient(uint32_t id) { return id >> 24; } static inline sysname_t fetch_request_id(uint32_t id) { return id & 0x00FFFFFF; } void __sys_internal_listener_loop(uint32_t *request, uint32_t request_size) { sysname_t id = me(); uint32_t self_fifo_info; uint32_t from_host_fifo_info; uint32_t to_host_fifo_info; self_fifo_info = fifo_fetch_info(id); from_host_fifo_info = fifo_sys_fetch_info(0); to_host_fifo_info = fifo_sys_fetch_info(1); while (true) { if (fetch_request(self_fifo_info, request, request_size)) { while (fifo_is_full(to_host_fifo_info, request_size)) { // Waiting for the recipient to read some of its pending requests... // Do we want to add some "sleep" here? } fifo_produce(to_host_fifo_info, request, request_size); } if (fetch_request(from_host_fifo_info, request, request_size)) { sysname_t recipient = fetch_recipient(request[0]); /* If a message is sent to the listener from the host, we interpret it as a shutdown order. */ if (recipient == id) break; request[0] = fetch_request_id(request[0]); extern void internal_actor_send(uint32_t recipient, uint32_t * request, uint32_t request_size); internal_actor_send(recipient, request, request_size); } // Waiting for some request... // Do we want to add some "sleep" here? } } ================================================ FILE: golang/uPIMulator/sdk/syslib/lshrdi3.c ================================================ /* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __lshrdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: logical a >> b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __lshrdi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); udwords input; udwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { result.s.high = 0; result.s.low = input.s.high >> (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.high = input.s.high >> b; result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_llsr(di_int a, si_int b) { return __lshrdi3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/macro_utils.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MACRO_UTILS_H #define DPUSYSCORE_MACRO_UTILS_H /** * @file macro_utils.h * @brief Provide utility macros. */ #define __STR(x) __STR_AGAIN(x) #define __STR_AGAIN(x) #x #define __CONCAT(x, y) __CONCAT_AGAIN(x, y) #define __CONCAT_AGAIN(x, y) x##y #define __REPEAT_0(x) #define __REPEAT_1(x) x(0) __REPEAT_0(x) #define __REPEAT_2(x) x(1) __REPEAT_1(x) #define __REPEAT_3(x) x(2) __REPEAT_2(x) #define __REPEAT_4(x) x(3) __REPEAT_3(x) #define __REPEAT_5(x) x(4) __REPEAT_4(x) #define __REPEAT_6(x) x(5) __REPEAT_5(x) #define __REPEAT_7(x) x(6) __REPEAT_6(x) #define __REPEAT_8(x) x(7) __REPEAT_7(x) #define __REPEAT_9(x) x(8) __REPEAT_8(x) #define __REPEAT_10(x) x(9) __REPEAT_9(x) #define __REPEAT_11(x) x(10) __REPEAT_10(x) #define __REPEAT_12(x) x(11) __REPEAT_11(x) #define __REPEAT_13(x) x(12) __REPEAT_12(x) #define __REPEAT_14(x) x(13) __REPEAT_13(x) #define __REPEAT_15(x) x(14) __REPEAT_14(x) #define __REPEAT_16(x) x(15) __REPEAT_15(x) #define __REPEAT_17(x) x(16) __REPEAT_16(x) #define __REPEAT_18(x) x(17) __REPEAT_17(x) #define __REPEAT_19(x) x(18) __REPEAT_18(x) #define __REPEAT_20(x) x(19) __REPEAT_19(x) #define __REPEAT_21(x) x(20) __REPEAT_20(x) #define __REPEAT_22(x) x(21) __REPEAT_21(x) #define __REPEAT_23(x) x(22) __REPEAT_22(x) #define __REPEAT_24(x) x(23) __REPEAT_23(x) #define __FOR_EACH_THREAD(x) __CONCAT(__REPEAT_, NR_THREADS)(x) #endif /* DPUSYSCORE_MACRO_UTILS_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/mcount.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ void __attribute__((naked, noinline, no_instrument_function)) mcount(void) { // Please see ret_mcount comment regarding why mcount references ret_mcount. __asm__ volatile("jump ret_mcount"); } void __attribute__((naked, noinline, no_instrument_function)) ret_mcount(void) { // ret_mcount is used in statistics mode, mcount *must* reference ret_mcount // so that ret_mcount symbol is not gc (remember that we patch the binary // when copying it to iram). __asm__ volatile("sh id4, thread_profiling, r23\n" "jump r23"); } ================================================ FILE: golang/uPIMulator/sdk/syslib/moddi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 signed division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); int64_t __moddi3(int64_t dividend, int64_t divider) { if (dividend >= 0) { if (divider >= 0) { return __udiv64(dividend, divider, 1); } else { return __udiv64(dividend, -divider, 1); } } else if (divider >= 0) { // Negative dividend, positive divider return -__udiv64(-dividend, divider, 1); } else { // Negative dividend, negative divider return -__udiv64(-dividend, -divider, 1); } } ================================================ FILE: golang/uPIMulator/sdk/syslib/modsi3.c ================================================ /* ===-- modsi3.c - Implement __modsi3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __modsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a % b */ extern long __div32(int, int); COMPILER_RT_ABI si_int __modsi3(si_int a, si_int b) { long res = __div32(a, b); return (int)res; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mram.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MRAM_H #define DPUSYSCORE_MRAM_H #include #include /** * @file mram.h * @brief MRAM Transfer Management. */ #define DPU_MRAM_HEAP_POINTER ((__mram_ptr void *)(&__sys_used_mram_end)) extern __mram_ptr __dma_aligned uint8_t __sys_used_mram_end[0]; /** * @fn mram_read * @brief Stores the specified number of bytes from MRAM to WRAM. * The number of bytes must be: * - at least 8 * - at most 2048 * - a multiple of 8 * * @param from source address in MRAM * @param to destination address in WRAM * @param nb_of_bytes number of bytes to transfer */ static inline void mram_read(const __mram_ptr void *from, void *to, unsigned int nb_of_bytes) { __builtin_dpu_ldma(to, from, nb_of_bytes); } /** * @fn mram_write * @brief Stores the specified number of bytes from WRAM to MRAM. * The number of bytes must be: * - at least 8 * - at most 2048 * - a multiple of 8 * * @param from source address in WRAM * @param to destination address in MRAM * @param nb_of_bytes number of bytes to transfer */ static inline void mram_write(const void *from, __mram_ptr void *to, unsigned int nb_of_bytes) { __builtin_dpu_sdma(from, to, nb_of_bytes); } #endif /* DPUSYSCORE_MRAM_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/mul32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int __attribute__((noinline)) __mulsi3(int a, int b) { int dest; __asm__ volatile(" jgtu %2, %1, __mulsi3_swap\n" " move r2, %1\n" " move r0, %2, true, __mulsi3_start\n" "__mulsi3_swap:\n" " move r2, %2\n" " move r0, %1\n" "__mulsi3_start:\n" " move r1, zero\n" " mul_step d0, r2, d0, 0 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 1 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 2 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 3 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 4 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 5 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 6 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 7 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 8 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 9 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 10, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 11, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 12, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 13, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 14, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 15, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 16, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 17, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 18, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 19, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 20, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 21, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 22, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 23, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 24, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 25, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 26, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 27, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 28, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 29, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 30, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 31, z, __mulsi3_exit\n" "__mulsi3_exit:\n" " move %0, r1\n" : "=r"(dest) : "r"(a), "r"(b)); return dest; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mul64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 multiplication emulation. * * A relatively fast emulation of 64x64 multiplication using byte multipliers. * Basically, the two operands X and Y are seen as byte polynomials: * - X = X0.2^0 + X1.2^8 + X2.2^16 + X3.2^24 + X4.2^32 + X5.2^40 + X6.2^48 + X7.2^56 * - Y = Y0.2^0 + Y1.2^8 + Y2.2^16 + Y3.2^24 + Y4.2^32 + Y5.2^40 + Y6.2^48 + Y7.2^56 * * The product Z is expressed as a similar polynomial. Since the result is 64 bits, * the function drops any coefficient for a power greater than 56, hence the following * formula: * Z = (X0.Y0).2^0 * + (X0.Y1 + X1.Y0).2^8 * + (X0.Y2 + X2.Y0 + X1.Y1).2^16 * + (X0.Y3 + X1.Y2 + X2.Y1 + X3.Y0).2^24 * + (X0.Y4 + X1.Y3 + X2.Y2 + X3.Y1 + X4.Y0).2^32 * etc. * * Each individual produce is computed with the native built-in 8x8 instructions. * Resulting processing time is in the magnitude of 150 instructions. * * The two operands are found in __D0 and the first kernel nano-stack entry. * The result goes into __R0 (lsbits) and __R1 (msbits). * Also, __R2 contains the return address register, instead of __RET__. */ #include static uint16_t _mul00(uint32_t a, uint32_t b) { #ifndef DPU return (a & 0xff) * (b & 0xff); #else uint32_t r; __asm__ volatile("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } static uint16_t _mul01(uint32_t a, uint32_t b) { #ifndef DPU return (a & 0xff) * ((b >> 8) & 0xff); #else uint32_t r; __asm__ volatile("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } #define _mul02(a, b) _mul00(a, (b >> 16)) #define _mul03(a, b) _mul01(a, (b >> 16)) static uint16_t _mul11(uint32_t a, uint32_t b) { #ifndef DPU return ((a >> 8) & 0xff) * ((b >> 8) & 0xff); #else uint32_t r; __asm__ volatile("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } static uint16_t _mul12(uint32_t a, uint32_t b) { #ifndef DPU return ((a >> 8) & 0xff) * ((b >> 16) & 0xff); #else uint32_t r = (b >> 16); __asm__ volatile("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(r) :); return r; #endif } #define _mul13(a, b) _mul11(a, (b >> 16)) #define _mul22(a, b) _mul00((a >> 16), (b >> 16)) #define _mul23(a, b) _mul01((a >> 16), (b >> 16)) #define _mul33(a, b) _mul11((a >> 16), (b >> 16)) #define mulx0y0(xl, yl) _mul00(xl, yl) #define mulx0y1(xl, yl) _mul01(xl, yl) #define mulx0y2(xl, yl) _mul02(xl, yl) #define mulx0y3(xl, yl) _mul03(xl, yl) #define mulx0y4(xl, yh) _mul00(xl, yh) #define mulx0y5(xl, yh) _mul01(xl, yh) #define mulx0y6(xl, yh) _mul02(xl, yh) #define mulx0y7(xl, yh) _mul03(xl, yh) #define mulx1y1(xl, yl) _mul11(xl, yl) #define mulx1y2(xl, yl) _mul12(xl, yl) #define mulx1y3(xl, yl) _mul13(xl, yl) #define mulx1y4(xl, yh) _mul01(yh, xl) #define mulx1y5(xl, yh) _mul11(xl, yh) #define mulx1y6(xl, yh) _mul12(xl, yh) #define mulx2y2(xl, yl) _mul22(xl, yl) #define mulx2y3(xl, yl) _mul23(xl, yl) #define mulx2y4(xl, yh) _mul02(yh, xl) #define mulx2y5(xl, yh) _mul12(yh, xl) #define mulx3y3(xl, yl) _mul33(xl, yl) #define mulx3y4(xl, yh) _mul03(yh, xl) // Symmetry... #define mulx1y0(xl, yl) mulx0y1(yl, xl) #define mulx2y0(xl, yl) mulx0y2(yl, xl) #define mulx2y1(xl, yl) mulx1y2(yl, xl) #define mulx3y0(xl, yl) mulx0y3(yl, xl) #define mulx3y1(xl, yl) mulx1y3(yl, xl) #define mulx3y2(xl, yl) mulx2y3(yl, xl) #define mulx4y0(xh, yl) mulx0y4(yl, xh) #define mulx4y1(xh, yl) mulx1y4(yl, xh) #define mulx4y2(xh, yl) mulx2y4(yl, xh) #define mulx4y3(xh, yl) mulx3y4(yl, xh) #define mulx5y0(xh, yl) mulx0y5(yl, xh) #define mulx5y1(xh, yl) mulx1y5(yl, xh) #define mulx5y2(xh, yl) mulx2y5(yl, xh) #define mulx6y0(xh, yl) mulx0y6(yl, xh) #define mulx6y1(xh, yl) mulx1y6(yl, xh) #define mulx7y0(xh, yl) mulx0y7(yl, xh) uint64_t __muldi3(uint64_t x, uint64_t y) { uint32_t xl = x; uint32_t xh = ((uint64_t)x >> 32); uint32_t yl = y; uint32_t yh = ((uint64_t)y >> 32); // Each fragment of the product. uint32_t p0, p1, p2, p3, p4, p5, p6, p7, rh; uint64_t rl; p0 = mulx0y0(xl, yl); rl = (uint64_t)p0; p1 = mulx0y1(xl, yl) + mulx1y0(xl, yl); rl += ((uint64_t)p1 << 8); p2 = mulx0y2(xl, yl) + mulx2y0(xl, yl) + mulx1y1(xl, yl); rl += ((uint64_t)p2 << 16); p3 = mulx0y3(xl, yl) + mulx3y0(xl, yl) + mulx1y2(xl, yl) + mulx2y1(xl, yl); rl += ((uint64_t)p3 << 24); p4 = mulx0y4(xl, yh) + mulx4y0(xh, yl) + mulx1y3(xl, yl) + mulx3y1(xl, yl) + mulx2y2(xl, yl); rh = p4; p5 = mulx0y5(xl, yh) + mulx5y0(xh, yl) + mulx1y4(xl, yh) + mulx4y1(xh, yl) + mulx2y3(xl, yl) + mulx3y2(xl, yl); rh += p5 << 8; p6 = mulx0y6(xl, yh) + mulx6y0(xh, yl) + mulx1y5(xl, yh) + mulx5y1(xh, yl) + mulx2y4(xl, yh) + mulx4y2(xh, yl) + mulx3y3(xl, yl); rh += p6 << 16; p7 = mulx0y7(xl, yh) + mulx7y0(xh, yl) + mulx1y6(xl, yh) + mulx6y1(xh, yl) + mulx2y5(xl, yh) + mulx5y2(xh, yl) + mulx3y4(xl, yh) + mulx4y3(xh, yl); rh += p7 << 24; return rl + (((uint64_t)rh) << 32); } ================================================ FILE: golang/uPIMulator/sdk/syslib/muldc3.c ================================================ /* ===-- muldc3.c - Implement __muldc3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __muldc3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #include "int_math.h" /* Returns: the product of a + ib and c + id */ COMPILER_RT_ABI Dcomplex __muldc3(double __a, double __b, double __c, double __d) { double __ac = __a * __c; double __bd = __b * __d; double __ad = __a * __d; double __bc = __b * __c; Dcomplex z; COMPLEX_REAL(z) = __ac - __bd; COMPLEX_IMAGINARY(z) = __ad + __bc; if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) { int __recalc = 0; if (crt_isinf(__a) || crt_isinf(__b)) { __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a); __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b); if (crt_isnan(__c)) __c = crt_copysign(0, __c); if (crt_isnan(__d)) __d = crt_copysign(0, __d); __recalc = 1; } if (crt_isinf(__c) || crt_isinf(__d)) { __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c); __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d); if (crt_isnan(__a)) __a = crt_copysign(0, __a); if (crt_isnan(__b)) __b = crt_copysign(0, __b); __recalc = 1; } if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || crt_isinf(__ad) || crt_isinf(__bc))) { if (crt_isnan(__a)) __a = crt_copysign(0, __a); if (crt_isnan(__b)) __b = crt_copysign(0, __b); if (crt_isnan(__c)) __c = crt_copysign(0, __c); if (crt_isnan(__d)) __d = crt_copysign(0, __d); __recalc = 1; } if (__recalc) { COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); } } return z; } ================================================ FILE: golang/uPIMulator/sdk/syslib/muldf3.c ================================================ //===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float multiplication // with the IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_mul_impl.inc" COMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dmul(fp_t a, fp_t b) { return __muldf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/mulodi4.c ================================================ /*===-- mulodi4.c - Implement __mulodi4 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulodi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: sets *overflow to 1 if a * b overflows */ COMPILER_RT_ABI di_int __mulodi4(di_int a, di_int b, int *overflow) { const int N = (int)(sizeof(di_int) * CHAR_BIT); const di_int MIN = (di_int)1 << (N - 1); const di_int MAX = ~MIN; *overflow = 0; di_int result = a * b; if (a == MIN) { if (b != 0 && b != 1) *overflow = 1; return result; } if (b == MIN) { if (a != 0 && a != 1) *overflow = 1; return result; } di_int sa = a >> (N - 1); di_int abs_a = (a ^ sa) - sa; di_int sb = b >> (N - 1); di_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return result; if (sa == sb) { if (abs_a > MAX / abs_b) *overflow = 1; } else { if (abs_a > MIN / -abs_b) *overflow = 1; } return result; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mulosi4.c ================================================ /*===-- mulosi4.c - Implement __mulosi4 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulosi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: sets *overflow to 1 if a * b overflows */ COMPILER_RT_ABI si_int __mulosi4(si_int a, si_int b, int *overflow) { const int N = (int)(sizeof(si_int) * CHAR_BIT); const si_int MIN = (si_int)1 << (N - 1); const si_int MAX = ~MIN; *overflow = 0; si_int result = a * b; if (a == MIN) { if (b != 0 && b != 1) *overflow = 1; return result; } if (b == MIN) { if (a != 0 && a != 1) *overflow = 1; return result; } si_int sa = a >> (N - 1); si_int abs_a = (a ^ sa) - sa; si_int sb = b >> (N - 1); si_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return result; if (sa == sb) { if (abs_a > MAX / abs_b) *overflow = 1; } else { if (abs_a > MIN / -abs_b) *overflow = 1; } return result; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mulsf3.c ================================================ //===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float multiplication // with the IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_mul_impl.inc" COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) { return __mulsf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/mulvdi3.c ================================================ /*===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: aborts if a * b overflows */ COMPILER_RT_ABI di_int __mulvdi3(di_int a, di_int b) { const int N = (int)(sizeof(di_int) * CHAR_BIT); const di_int MIN = (di_int)1 << (N - 1); const di_int MAX = ~MIN; if (a == MIN) { if (b == 0 || b == 1) return a * b; compilerrt_abort(); } if (b == MIN) { if (a == 0 || a == 1) return a * b; compilerrt_abort(); } di_int sa = a >> (N - 1); di_int abs_a = (a ^ sa) - sa; di_int sb = b >> (N - 1); di_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return a * b; if (sa == sb) { if (abs_a > MAX / abs_b) compilerrt_abort(); } else { if (abs_a > MIN / -abs_b) compilerrt_abort(); } return a * b; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mulvsi3.c ================================================ /* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: aborts if a * b overflows */ COMPILER_RT_ABI si_int __mulvsi3(si_int a, si_int b) { const int N = (int)(sizeof(si_int) * CHAR_BIT); const si_int MIN = (si_int)1 << (N - 1); const si_int MAX = ~MIN; if (a == MIN) { if (b == 0 || b == 1) return a * b; compilerrt_abort(); } if (b == MIN) { if (a == 0 || a == 1) return a * b; compilerrt_abort(); } si_int sa = a >> (N - 1); si_int abs_a = (a ^ sa) - sa; si_int sb = b >> (N - 1); si_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return a * b; if (sa == sb) { if (abs_a > MAX / abs_b) compilerrt_abort(); } else { if (abs_a > MIN / -abs_b) compilerrt_abort(); } return a * b; } ================================================ FILE: golang/uPIMulator/sdk/syslib/mutex.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MUTEX_H #define DPUSYSCORE_MUTEX_H /** * @file mutex.h * @brief Mutual exclusions. * * A mutex ensures mutual exclusion between threads: only one runtime can have the mutex at a time, blocking all the * other threads trying to take the mutex. * * @internal All the mutexes are stored in a table in WRAM. In this table, each byte represents a mutex, * and can be accessed directly by taking the base address of the table and adding it the sysname of the mutex * we want (thus, the sysname should be an integer in the range [0; NB_MUTEX -1]). The result of * this addition is what a mutex_get will return. * A lock is made by using an lb_a instruction on the address of the mutex given as a parameter. * An unlock is made by using an sb_r instruction on the address of the mutex given as a parameter. * The id of the runtime doing the unlock is what is currently stored at the address of the mutex. * The base address of this table is associated with the pointer defined by __MUTEX_TABLE__. */ #include #include #include #include /** * @typedef mutex_id_t * @brief A mutex object reference, as declared by MUTEX_INIT. */ typedef uint8_t *mutex_id_t; /** * @def MUTEX_GET * @hideinitializer * @brief Return the symbol to use when using the mutex associated to the given name. */ #define MUTEX_GET(_name) _name /** * @def MUTEX_INIT * @hideinitializer * @brief Declare and initialize a mutex associated to the given name. */ #define MUTEX_INIT(_name) \ ATOMIC_BIT_INIT(__CONCAT(mutex_, _name)); \ const mutex_id_t MUTEX_GET(_name) = &ATOMIC_BIT_GET(__CONCAT(mutex_, _name)) /** * @fn mutex_lock * @brief Takes the lock on the given mutex. * @param mutex the mutex we want to lock */ static inline void mutex_lock(mutex_id_t mutex) { __asm__ volatile("acquire %[mtx], 0, nz, ." : : [mtx] "r"(mutex) :); } /** * @fn mutex_trylock * @brief Tries to take the lock on the given mutex. If the lock is already taken, returns immediately. * @param mutex the mutex we want to lock * @return Whether the mutex has been successfully locked. */ static inline bool mutex_trylock(mutex_id_t mutex) { bool result = true; __asm__ volatile("acquire %[mtx], 0, z, .+2; move %[res], 0" : [res] "+r"(result) : [mtx] "r"(mutex) :); return result; } /** * @fn mutex_unlock * @brief Releases the lock on the given mutex. * @param mutex the mutex we want to unlock */ static inline void mutex_unlock(mutex_id_t mutex) { __asm__ volatile("release %[mtx], 0, nz, .+1" : : [mtx] "r"(mutex) :); } #endif /* DPUSYSCORE_MUTEX_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/negdf2.c ================================================ //===-- lib/negdf2.c - double-precision negation ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float negation. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __negdf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dneg(fp_t a) { return __negdf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/negdi2.c ================================================ /* ===-- negdi2.c - Implement __negdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ COMPILER_RT_ABI di_int __negdi2(di_int a) { /* Note: this routine is here for API compatibility; any sane compiler * should expand it inline. */ return -a; } ================================================ FILE: golang/uPIMulator/sdk/syslib/negsf2.c ================================================ //===-- lib/negsf2.c - single-precision negation ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float negation. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __negsf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fneg(fp_t a) { return __negsf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/negvdi2.c ================================================ /* ===-- negvdi2.c - Implement __negvdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negvdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ /* Effects: aborts if -a overflows */ COMPILER_RT_ABI di_int __negvdi2(di_int a) { const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT) - 1); if (a == MIN) compilerrt_abort(); return -a; } ================================================ FILE: golang/uPIMulator/sdk/syslib/negvsi2.c ================================================ /* ===-- negvsi2.c - Implement __negvsi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negvsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ /* Effects: aborts if -a overflows */ COMPILER_RT_ABI si_int __negvsi2(si_int a) { const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT) - 1); if (a == MIN) compilerrt_abort(); return -a; } ================================================ FILE: golang/uPIMulator/sdk/syslib/paritydi2.c ================================================ /* ===-- paritydi2.c - Implement __paritydi2 -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __paritydi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: 1 if number of bits is odd else returns 0 */ COMPILER_RT_ABI si_int __paritydi2(di_int a) { dwords x; x.all = a; return __paritysi2(x.s.high ^ x.s.low); } ================================================ FILE: golang/uPIMulator/sdk/syslib/paritysi2.c ================================================ /* ===-- paritysi2.c - Implement __paritysi2 -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __paritysi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: 1 if number of bits is odd else returns 0 */ COMPILER_RT_ABI si_int __paritysi2(si_int a) { su_int x = (su_int)a; x ^= x >> 16; x ^= x >> 8; x ^= x >> 4; return (0x6996 >> (x & 0xF)) & 1; } ================================================ FILE: golang/uPIMulator/sdk/syslib/perfcounter.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #define BIT_IMPRECISION 4 perfcounter_t perfcounter_get(void) { uint32_t reg_value; __asm__ volatile("time %[r]" : [r] "=r"(reg_value)); return ((perfcounter_t)reg_value) << BIT_IMPRECISION; } #ifndef DPU_PROFILING perfcounter_t perfcounter_config(perfcounter_config_t config, bool reset_value) { uint32_t reg_value; uint32_t reg_config = (reset_value ? 1 : 0) | (config << 1); __asm__ volatile("time_cfg %[r], %[c]" : [r] "=r"(reg_value) : [c] "r"(reg_config)); return ((perfcounter_t)reg_value) << BIT_IMPRECISION; } #endif /* !DPU_PROFILING */ ================================================ FILE: golang/uPIMulator/sdk/syslib/perfcounter.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_PERFCOUNTER_H #define DPUSYSCORE_PERFCOUNTER_H #include #include /** * @file perfcounter.h * @brief Utilities concerning the performance counter register. * */ /** * @typedef perfcounter_t * @brief A value which can be stored by the performance counter. */ typedef uint64_t perfcounter_t; /** * @enum perfcounter_config_t * @brief A configuration for the performance counter, defining what should be counted. * * @var COUNT_SAME keep the previous configuration * @var COUNT_CYCLES switch to counting clock cycles * @var COUNT_INSTRUCTIONS switch to counting executed instructions * @var COUNT_NOTHING does not count anything */ typedef enum _perfcounter_config_t { COUNT_SAME = 0, COUNT_CYCLES = 1, COUNT_INSTRUCTIONS = 2, COUNT_NOTHING = 3, } perfcounter_config_t; /** * @def CLOCKS_PER_SEC * @hideinitializer * @brief A number used to convert the value returned by the perfcounter_get and perfcounter_config functions into seconds, * when counting clock cycles. */ extern const volatile uint32_t CLOCKS_PER_SEC; /** * @fn perfcounter_get * @brief Fetch the value of the performance counter register. * * @return The current value of the performance counter register, or undefined if perfcounter_config has not been called before. */ perfcounter_t perfcounter_get(void); #ifndef DPU_PROFILING /** * @fn perfcounter_config * @brief Configure the performance counter behavior. * * This function cannot be used when profiling an application. * * @param config The new behavior for the performance counter register * @param reset_value Whether the performance counter register should be set to 0 * * @return The current value of the performance counter register, or undefined if perfcounter_config has not been called before. */ perfcounter_t perfcounter_config(perfcounter_config_t config, bool reset_value); #else #define perfcounter_config(config, reset_value) \ do { \ } while (0) #endif /* !DPU_PROFILING */ #endif /* DPUSYSCORE_PERFCOUNTER_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/popcountdi2.c ================================================ /* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __popcountdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: count of 1 bits */ COMPILER_RT_ABI si_int __popcountdi2(di_int a) { du_int x2 = (du_int)a; x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL); /* Every 2 bits holds the sum of every pair of bits (32) */ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL); /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL; /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */ su_int x = (su_int)(x2 + (x2 >> 32)); /* The lower 32 bits hold four 16 bit sums (5 significant bits). */ /* Upper 32 bits are garbage */ x = x + (x >> 16); /* The lower 16 bits hold two 32 bit sums (6 significant bits). */ /* Upper 16 bits are garbage */ return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */ } ================================================ FILE: golang/uPIMulator/sdk/syslib/popcountsi2.c ================================================ /* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __popcountsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: count of 1 bits */ COMPILER_RT_ABI si_int __popcountsi2(si_int a) { su_int x = (su_int)a; x = x - ((x >> 1) & 0x55555555); /* Every 2 bits holds the sum of every pair of bits */ x = ((x >> 2) & 0x33333333) + (x & 0x33333333); /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */ x = (x + (x >> 4)) & 0x0F0F0F0F; /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */ x = (x + (x >> 16)); /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/ /* Upper 16 bits are garbage */ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */ } ================================================ FILE: golang/uPIMulator/sdk/syslib/powidf2.c ================================================ /* ===-- powidf2.cpp - Implement __powidf2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __powidf2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a ^ b */ COMPILER_RT_ABI double __powidf2(double a, si_int b) { const int recip = b < 0; double r = 1; while (1) { if (b & 1) r *= a; b /= 2; if (b == 0) break; a *= a; } return recip ? 1 / r : r; } ================================================ FILE: golang/uPIMulator/sdk/syslib/powisf2.c ================================================ /*===-- powisf2.cpp - Implement __powisf2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __powisf2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a ^ b */ COMPILER_RT_ABI float __powisf2(float a, si_int b) { const int recip = b < 0; float r = 1; while (1) { if (b & 1) r *= a; b /= 2; if (b == 0) break; a *= a; } return recip ? 1 / r : r; } ================================================ FILE: golang/uPIMulator/sdk/syslib/profiling.c ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #ifdef DPU_PROFILING void __attribute__((no_instrument_function)) profiling_start(dpu_profiling_t *context) { thread_id_t tid = me(); uint32_t perfcounter_value; if (unlikely(context->start[tid] != PROFILING_RESET_VALUE)) { __asm__("fault " __STR(__FAULT_ALREADY_PROFILING__)); unreachable(); } __asm__ volatile("time %[r]" : [r] "=r"(perfcounter_value)); context->start[tid] = perfcounter_value; } void __attribute__((no_instrument_function)) profiling_stop(dpu_profiling_t *context) { thread_id_t tid = me(); uint32_t perfcounter_value; if (unlikely(context->start[tid] == PROFILING_RESET_VALUE)) { __asm__("fault " __STR(__FAULT_NOT_PROFILING__)); unreachable(); } __asm__ volatile("time %[r]" : [r] "=r"(perfcounter_value)); context->count[tid] += perfcounter_value - context->start[tid]; context->start[tid] = PROFILING_RESET_VALUE; } #endif /* DPU_PROFILING */ ================================================ FILE: golang/uPIMulator/sdk/syslib/profiling.h ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_PROFILING_H #define DPUSYSCORE_PROFILING_H /** * @file profiling.h * @brief Code section profiling management. */ #include #include #include #define PROFILING_RESET_VALUE (UINT32_MAX) /** * @def PROFILING_INIT * @hideinitializer * @brief Declare and initialize a profiling context associated to the given name. */ #define PROFILING_INIT(_name) \ __section(".dpu_profiling") dpu_profiling_t _name = { \ .start = { [0 ...(NR_THREADS - 1)] = PROFILING_RESET_VALUE }, \ .count = { [0 ...(NR_THREADS - 1)] = 0 }, \ } #ifdef DPU_PROFILING /** * @fn profiling_start * @brief Start profiling a code section. * * This function saves the perfcounter current value in the profiling context. * * @param context the profiling context to use. */ void profiling_start(dpu_profiling_t *context); /** * @fn profiling_stop * @brief Stop profiling a code section. * * This function gets the perfcounter current value and computes the number of cyles spent in the code section. * The profiling_start function must be called beforehand. * * @param context the profiling context to use. */ void profiling_stop(dpu_profiling_t *context); #else #define profiling_start(context) \ do { \ } while (0) #define profiling_stop(context) \ do { \ } while (0) #endif /* DPU_PROFILING */ #endif /* DPUSYSCORE_PROFILING_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/profiling_internals.h ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* Shared with backends */ #ifndef DPUSYSCORE_PROFILING_INTERNALS_H #define DPUSYSCORE_PROFILING_INTERNALS_H /** * @file profiling_internals.h * @brief Code section profiling internals. */ #include #ifndef NR_THREADS #ifdef DPU_NR_THREADS #define NR_THREADS DPU_NR_THREADS #else #error "DPU_NR_THREADS and NR_THREADS are undefined" #endif /* DPU_NR_THREADS */ #endif /* !NR_THREADS */ /** * @typedef dpu_profiling_t * @brief A profiling context. */ typedef struct { uint32_t start[NR_THREADS]; uint32_t count[NR_THREADS]; } dpu_profiling_t; #endif /* DPUSYSCORE_PROFILING_INTERNALS_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/sem.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include void sem_take(struct sem_t *sem) { unsigned char lock = sem->lock; __acquire(lock, "0"); char count = sem->count - 1; thread_id_t tid = me(); if (count < 0) { unsigned char last = sem->wait_queue; if (last != __EMPTY_WAIT_QUEUE) { unsigned char first = __WAIT_QUEUE_TABLE[last]; __WAIT_QUEUE_TABLE[tid] = first; __WAIT_QUEUE_TABLE[last] = tid; } else { __WAIT_QUEUE_TABLE[tid] = tid; } sem->wait_queue = tid; sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); __stop(); } else { sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); } } void sem_give(struct sem_t *sem) { unsigned char lock = sem->lock; __acquire(lock, "0"); unsigned char count = sem->count + 1; unsigned char last = sem->wait_queue; if (last != __EMPTY_WAIT_QUEUE) { unsigned char first = __WAIT_QUEUE_TABLE[last]; if (first == last) { sem->wait_queue = __EMPTY_WAIT_QUEUE; } else { __WAIT_QUEUE_TABLE[last] = __WAIT_QUEUE_TABLE[first]; } __resume(first, "0"); } sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); } ================================================ FILE: golang/uPIMulator/sdk/syslib/sem.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SEM_H #define DPUSYSCORE_SEM_H /** * @file sem.h * @brief Synchronization with semaphores. * * A semaphore is characterized by a counter and a wait queue. It provides two functions: * * - Take: the counter is decremented by 1. If the counter is negative, the runtime is blocked (stop) and placed in the * semaphore's wait queue, waiting to be resume by another runtime. * - Give: the counter is incremented by 1. If the counter was negative before the increment, the runtime resumes the execution * of the first runtime waiting in the waiting queue. In all the cases, the runtime continues its own execution. * */ #include #include #include /** * @typedef sem_t * @brief A semaphore object, as declared by SEMAPHORE_INIT. */ typedef struct sem_t { uint8_t wait_queue; uint8_t count; uint8_t initial_count; uint8_t lock; } sem_t; /** * @def SEMAPHORE_INIT * @hideinitializer * @brief Declare and initialize a semaphore associated to the given name. */ /* clang-format off */ #define SEMAPHORE_INIT(_name, _counter) \ _Static_assert((_counter < 128) && (_counter >= -127), "semaphore counter must be encoded on a byte"); \ ATOMIC_BIT_INIT(__CONCAT(semaphore_, _name)); \ extern sem_t (_name); \ __asm__(".section .data." __STR(_name) "\n" \ ".type " __STR(_name) ",@object\n" \ ".globl " __STR(_name) "\n" \ ".p2align 2\n" __STR(_name) ":\n" \ ".byte 0xFF\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(ATOMIC_BIT_GET(__CONCAT(semaphore_, _name))) "\n" \ ".size " __STR(_name) ", 4\n" \ ".text"); /* clang-format on */ /** * @fn sem_take * @brief Takes one unit in the given semaphore (cf Take definition). * @param sem the semaphore we want to take */ void sem_take(sem_t *sem); /** * @fn sem_give * @brief Gives on unit in the given semaphore (cf Give definition). * @param sem the semaphore we want to give */ void sem_give(sem_t *sem); #endif /* DPUSYSCORE_SEM_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SEQREAD_H #define DPUSYSCORE_SEQREAD_H /** * @file seqread.h * @brief Sequential reading of items in MRAM. * * A sequential reader allows to parse a contiguous area in MRAM in sequence. * For example, if the MRAM contains an array of N structures, a sequential * reader on this array will automatically fetch the data into WRAM, thus * simplify the iterative loop on the elements. * * The size of cached area is defined by default but can be overriden by * defining this value in SEQREAD_CACHE_SIZE. * * The use of a sequential reader implies: * * - first, to allocate some storage in WRAM to cache the items, using seqread_alloc. * - then to initialize a reader on the MRAM area, via seqread_init * - finally to iterate on the elements, invoking seqread_get whenever a new item is accessed. * */ #include #include #include #ifndef SEQREAD_CACHE_SIZE /** * @def SEQREAD_CACHE_SIZE * @hideinitializer * @brief Size of caches used by seqread. */ #define SEQREAD_CACHE_SIZE 256 #endif _Static_assert(SEQREAD_CACHE_SIZE == 32 || SEQREAD_CACHE_SIZE == 64 || SEQREAD_CACHE_SIZE == 128 || SEQREAD_CACHE_SIZE == 256 || SEQREAD_CACHE_SIZE == 512 || SEQREAD_CACHE_SIZE == 1024, "seqread error: invalid cache size defined"); #define __SEQREAD_FCT(suffix) __CONCAT(__CONCAT(seqread, SEQREAD_CACHE_SIZE), suffix) #define __SEQREAD_ALLOC __SEQREAD_FCT(_alloc) #define __SEQREAD_INIT __SEQREAD_FCT(_init) #define __SEQREAD_GET __SEQREAD_FCT(_get) #define __SEQREAD_TELL __SEQREAD_FCT(_tell) #define __SEQREAD_SEEK __SEQREAD_FCT(_seek) /** * @typedef seqreader_buffer_t * @brief An buffer to use to initial a sequential reader. */ typedef uintptr_t seqreader_buffer_t; /** * @typedef seqreader_t * @brief An object used to perform sequential reading of MRAM. */ typedef struct { seqreader_buffer_t wram_cache; uintptr_t mram_addr; } seqreader_t; seqreader_buffer_t __SEQREAD_ALLOC(); /** * @fn seqread_alloc * @brief Initializes an area in WRAM to cache the read buffers. * * Notice that this buffer can be re-used for different sequential reads, * as long as it is initialized each time to a new buffer in MRAM. * * @return A pointer to the allocated cache base address. */ #define seqread_alloc __SEQREAD_ALLOC void * __SEQREAD_INIT(seqreader_buffer_t cache, __mram_ptr void *mram_addr, seqreader_t *reader); /** * @fn seqread_init * @brief Creates a sequential reader. * * The reader is associated to an existing cache in WRAM, created with * seqread_alloc and a contiguous area of data in MRAM. The function * loads the first pages of data into the cache and provides a pointer * to the first byte in cache actually mapping the expected data. * * Notice that the provided MRAM address does not need to be aligned on * any constraint: the routine does the alignment automatically. * * @param cache the reader's cache in WRAM * @param mram_addr the buffer address in MRAM * @param reader the sequential reader to init to the supplied MRAM address * @return A ptr to the first byte in cache corresponding to the MRAM address */ #define seqread_init __SEQREAD_INIT void * __SEQREAD_GET(void *ptr, uint32_t inc, seqreader_t *reader); /** * @fn seqread_get * @brief Fetches the next item in a sequence. * * This operation basically consists in incrementing the pointer that goes * through the mapped area of memory. The function automatically reloads * data from cache if necessary. * * As a result, the provided pointer to the cache area is set to its new value. * * The provided increment must be less than SEQREAD_CACHE_SIZE. The reader's * behavior is undefined if the increment exceeds this value. * * @param ptr the incremented pointer * @param inc the number of bytes added to this pointer * @param reader a pointer to the sequential reader * @return The updated pointer value. */ #define seqread_get __SEQREAD_GET void * __SEQREAD_SEEK(__mram_ptr void *mram_addr, seqreader_t *reader); /** * @fn seqread_seek * @brief Set the position of the cache to the supplied MRAM address * * Update automatically the cache if necessary. * * @param mram_addr the new buffer address in MRAM * @param reader a pointer to the sequential reader * @return A ptr to the first byte in cache corresponding to the MRAM address */ #define seqread_seek __SEQREAD_SEEK __mram_ptr void * __SEQREAD_TELL(void *ptr, seqreader_t *reader); /** * @fn seqread_tell * @brief Get the MRAM address corresponding to the supplied ptr in the cache * * @param ptr a pointer in the cache * @param reader a pointer to the sequential reader * @return A ptr to the MRAM address corresponding to the supplied pointer in the cache */ #define seqread_tell __SEQREAD_TELL #endif /* DPUSYSCORE_SEQREAD_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread.inc ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #define PAGE_SIZE (SEQREAD_CACHE_SIZE) #define PAGE_ALLOC_SIZE (2 * PAGE_SIZE) #define PAGE_OFF_MASK (PAGE_SIZE - 1) #define PAGE_IDX_MASK (~PAGE_OFF_MASK) #define MRAM_READ_PAGE(from, to) mram_read((__mram_ptr void *)(from), (void *)(to), PAGE_ALLOC_SIZE) extern void * mem_alloc_nolock(size_t size); ATOMIC_BIT_EXTERN(__heap_pointer); seqreader_buffer_t __SEQREAD_ALLOC(void) { ATOMIC_BIT_ACQUIRE(__heap_pointer); unsigned int heap_pointer = __HEAP_POINTER; seqreader_buffer_t pointer = (seqreader_buffer_t)((heap_pointer + PAGE_OFF_MASK) & PAGE_IDX_MASK); size_t size = pointer + PAGE_ALLOC_SIZE - heap_pointer; /* We already compute the return pointer * mem_alloc_nolock is only used to really reserve the memory area in the heap */ mem_alloc_nolock(size); ATOMIC_BIT_RELEASE(__heap_pointer); return pointer; } void * __SEQREAD_INIT(seqreader_buffer_t cache, __mram_ptr void *mram_addr, seqreader_t *reader) { reader->wram_cache = cache; reader->mram_addr = (uintptr_t)(1 << __DPU_MRAM_SIZE_LOG2); return __SEQREAD_SEEK(mram_addr, reader); } void * __SEQREAD_GET(void *ptr, uint32_t inc, seqreader_t *reader) { return (void *)__builtin_dpu_seqread_get((uintptr_t)ptr, inc, reader, PAGE_SIZE); } void * __SEQREAD_SEEK(__mram_ptr void *mram_addr, seqreader_t *reader) { uintptr_t target_addr = (uintptr_t)mram_addr; uintptr_t current_addr = (uintptr_t)reader->mram_addr; uintptr_t wram_cache = (uintptr_t)reader->wram_cache; uintptr_t mram_offset = target_addr - current_addr; if ((mram_offset & PAGE_IDX_MASK) != 0) { uintptr_t target_addr_idx_page = target_addr & PAGE_IDX_MASK; MRAM_READ_PAGE(target_addr_idx_page, wram_cache); mram_offset = target_addr & PAGE_OFF_MASK; reader->mram_addr = target_addr_idx_page; } return (void *)(mram_offset + wram_cache); } __mram_ptr void * __SEQREAD_TELL(void *ptr, seqreader_t *reader) { return (__mram_ptr void *)((uintptr_t)reader->mram_addr + ((uintptr_t)ptr & PAGE_OFF_MASK)); } ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread1024.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 1024 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread128.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 128 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread256.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 256 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 32 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread512.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 512 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/seqread64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 64 #include ================================================ FILE: golang/uPIMulator/sdk/syslib/soft_cache.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include unsigned long __sw_cache_buffer[NR_THREADS] __dma_aligned __used; ================================================ FILE: golang/uPIMulator/sdk/syslib/soft_cache.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SOFT_CACHE_H #define DPUSYSCORE_SOFT_CACHE_H /** * @file soft_cache.h * @brief Software cache * * The software cache mechanism emulates a hardware cache to transparently load and store data from and to the * MRAM. * * This mechanism is quite slow, thus would only be used during the development process, to simplify the code. * * This module defines: * * - A procedure to start the software cache, by creating a "virtual TLB" in the system, along with an area in WRAM to contain * the cached MRAM pages * - A procedure to flush the cache at the end of an execution, ensuring that the data in MRAM are consistent with the cached * data * - The special C directive "__mram", used to declare a pointer directly representing a buffer in MRAM. * * An MRAM pointer is mapped by the caching system. As a consequence, any access to data within this buffer is trapped * by a cache load or store procedure, transparently performing the required memory transactions to fetch and write back * the data. * */ #include #endif /* DPUSYSCORE_SOFT_CACHE_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/subdf3.c ================================================ //===-- lib/adddf3.c - Double-precision subtraction ---------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float subtraction with the // IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t __subdf3(fp_t a, fp_t b) { return __adddf3(a, fromRep(toRep(b) ^ signBit)); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dsub(fp_t a, fp_t b) { return __subdf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/subsf3.c ================================================ //===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float subtraction with the // IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t __subsf3(fp_t a, fp_t b) { return __addsf3(a, fromRep(toRep(b) ^ signBit)); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) { return __subsf3(a, b); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/subvdi3.c ================================================ /* ===-- subvdi3.c - Implement __subvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __subvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a - b */ /* Effects: aborts if a - b overflows */ COMPILER_RT_ABI di_int __subvdi3(di_int a, di_int b) { di_int s = (du_int)a - (du_int)b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; } ================================================ FILE: golang/uPIMulator/sdk/syslib/subvsi3.c ================================================ /* ===-- subvsi3.c - Implement __subvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __subvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a - b */ /* Effects: aborts if a - b overflows */ COMPILER_RT_ABI si_int __subvsi3(si_int a, si_int b) { si_int s = (su_int)a - (su_int)b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; } ================================================ FILE: golang/uPIMulator/sdk/syslib/sysdef.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SYSDEF_H #define DPUSYSCORE_SYSDEF_H /** * @file sysdef.h * @brief Provides useful system abstractions. */ /** * @typedef thread_id_t * @brief A unique runtime number. */ typedef unsigned int thread_id_t; /** * @typedef sysname_t * @brief A system name. * * Used to name system structures, like mutexes, semaphores, meetpoints, etc... In practice, system names * are integers, representing a unique identifier for the given type of structure. */ typedef unsigned int sysname_t; #endif /* DPUSYSCORE_SYSDEF_H */ ================================================ FILE: golang/uPIMulator/sdk/syslib/truncdfhf2.c ================================================ //===-- lib/truncdfhf2.c - double -> half conversion --------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_DOUBLE #define DST_HALF #include "fp_trunc_impl.inc" COMPILER_RT_ABI uint16_t __truncdfhf2(double a) { return __truncXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI uint16_t __aeabi_d2h(double a) { return __truncdfhf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/truncdfsf2.c ================================================ //===-- lib/truncdfsf2.c - double -> single conversion ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_DOUBLE #define DST_SINGLE #include "fp_trunc_impl.inc" COMPILER_RT_ABI float __truncdfsf2(double a) { return __truncXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_d2f(double a) { return __truncdfsf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/truncsfhf2.c ================================================ //===-- lib/truncsfhf2.c - single -> half conversion --------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_SINGLE #define DST_HALF #include "fp_trunc_impl.inc" // Use a forwarding definition and noinline to implement a poor man's alias, // as there isn't a good cross-platform way of defining one. COMPILER_RT_ABI NOINLINE uint16_t __truncsfhf2(float a) { return __truncXfYf2__(a); } COMPILER_RT_ABI uint16_t __gnu_f2h_ieee(float a) { return __truncsfhf2(a); } #if defined(__ARM_EABI__) AEABI_RTABI uint16_t __aeabi_f2h(float a) { return __truncsfhf2(a); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/ucmpdi2.c ================================================ /* ===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ucmpdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 */ COMPILER_RT_ABI si_int __ucmpdi2(du_int a, du_int b) { udwords x; x.all = a; udwords y; y.all = b; if (x.s.high < y.s.high) return 0; if (x.s.high > y.s.high) return 2; if (x.s.low < y.s.low) return 0; if (x.s.low > y.s.low) return 2; return 1; } #ifdef __ARM_EABI__ /* Returns: if (a < b) returns -1 * if (a == b) returns 0 * if (a > b) returns 1 */ COMPILER_RT_ABI si_int __aeabi_ulcmp(di_int a, di_int b) { return __ucmpdi2(a, b) - 1; } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/udiv64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 multiplication unsigned division. */ #include #include static unsigned int __clz__(uint64_t x) { return __builtin_clzl(x); } uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder) { uint64_t dxo = dividend, dxe = 0; if (divider == 0) goto division_by_zero; if (divider > dividend) { if (ask_remainder == 0) return 0; else return dividend; } // Mimic the div_step. /// div_step functionality: // if (Dxo >= (Ra<< #u5)) { // Dxo = Dxo - (Ra<< #u5); // Dxe = (Dxe << 1) | 1; // } else { // Dxe = Dxe << 1; // } int dividerl0 = __clz__(divider), dividendl0 = __clz__(dividend); int i = dividerl0 - dividendl0; for (; i >= 0; i--) { uint64_t pivot = ((uint64_t)divider << i); if (dxo >= pivot) { dxo = dxo - pivot; dxe = ((uint64_t)dxe << 1) | 1L; } else { dxe = (uint64_t)dxe << 1; } } if (ask_remainder == 1) return dxo; else return dxe; division_by_zero: __asm__ volatile("fault " __STR(__FAULT_DIVISION_BY_ZERO__)); unreachable(); } ================================================ FILE: golang/uPIMulator/sdk/syslib/udivdi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 unsigned division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); uint64_t __udivdi3(uint64_t dividend, uint64_t divider) { return __udiv64(dividend, divider, 0); } ================================================ FILE: golang/uPIMulator/sdk/syslib/udivmodsi4.c ================================================ /*===-- udivmodsi4.c - Implement __udivmodsi4 ------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __udivmodsi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b, *rem = a % b */ extern unsigned long __udiv32(unsigned int, unsigned int); COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem) { unsigned long res = __udiv32(a, b); *rem = (unsigned int)res; return (unsigned int)(res >> 32); } ================================================ FILE: golang/uPIMulator/sdk/syslib/udivsi3.c ================================================ /* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __udivsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b */ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ /* This function should not call __divsi3! */ COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d) { const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; su_int q; su_int r; unsigned sr; /* special cases */ if (d == 0) return 0; /* ?! */ if (n == 0) return 0; sr = __builtin_clz(d) - __builtin_clz(n); /* 0 <= sr <= n_uword_bits - 1 or sr large */ if (sr > n_uword_bits - 1) /* d > r */ return 0; if (sr == n_uword_bits - 1) /* d == 1 */ return n; ++sr; /* 1 <= sr <= n_uword_bits - 1 */ /* Not a special case */ q = n << (n_uword_bits - sr); r = n >> sr; su_int carry = 0; for (; sr > 0; --sr) { /* r:q = ((r:q) << 1) | carry */ r = (r << 1) | (q >> (n_uword_bits - 1)); q = (q << 1) | carry; /* carry = 0; * if (r.all >= d.all) * { * r.all -= d.all; * carry = 1; * } */ const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1); carry = s & 1; r -= d & s; } q = (q << 1) | carry; return q; } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_uidiv(su_int n, su_int d) { return __udivsi3(n, d); } #endif ================================================ FILE: golang/uPIMulator/sdk/syslib/umoddi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 unsigned remainder. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); uint64_t __umoddi3(uint64_t dividend, uint64_t divider) { return __udiv64(dividend, divider, 1); } ================================================ FILE: golang/uPIMulator/sdk/syslib/umodsi3.c ================================================ /* ===-- umodsi3.c - Implement __umodsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __umodsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a % b */ extern unsigned long __udiv32(unsigned int, unsigned int); COMPILER_RT_ABI su_int __umodsi3(su_int a, su_int b) { unsigned long res = __udiv32(a, b); return (unsigned int)res; } ================================================ FILE: golang/uPIMulator/sdk/syslib/waitqueue.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include unsigned char __attribute__((used)) __sys_wq_table[NR_THREADS] = { [0 ...(NR_THREADS - 1)] = __EMPTY_WAIT_QUEUE }; ================================================ FILE: golang/uPIMulator/src/abi/encoding/ascii_encoder.go ================================================ package encoding type AsciiEncoder struct { table map[string]uint8 inverted_table map[uint8]string unknown string } func (this *AsciiEncoder) Init() { this.table = make(map[string]uint8, 0) this.inverted_table = make(map[uint8]string, 0) this.table["\t"] = 9 this.table[" "] = 32 this.table["!"] = 33 this.table["\""] = 34 this.table["#"] = 35 this.table["$"] = 36 this.table["%"] = 37 this.table["&"] = 38 this.table["'"] = 39 this.table["("] = 40 this.table[")"] = 41 this.table["*"] = 42 this.table["+"] = 43 this.table[","] = 44 this.table["-"] = 45 this.table["."] = 46 this.table["/"] = 47 this.table["0"] = 48 this.table["1"] = 49 this.table["2"] = 50 this.table["3"] = 51 this.table["4"] = 52 this.table["5"] = 53 this.table["6"] = 54 this.table["7"] = 55 this.table["8"] = 56 this.table["9"] = 57 this.table[":"] = 58 this.table[""] = 59 this.table["<"] = 60 this.table["="] = 61 this.table[">"] = 62 this.table["?"] = 63 this.table["@"] = 64 this.table["A"] = 65 this.table["B"] = 66 this.table["C"] = 67 this.table["D"] = 68 this.table["E"] = 69 this.table["F"] = 70 this.table["G"] = 71 this.table["H"] = 72 this.table["I"] = 73 this.table["J"] = 74 this.table["K"] = 75 this.table["L"] = 76 this.table["M"] = 77 this.table["N"] = 78 this.table["O"] = 79 this.table["P"] = 80 this.table["Q"] = 81 this.table["R"] = 82 this.table["S"] = 83 this.table["T"] = 84 this.table["U"] = 85 this.table["V"] = 86 this.table["W"] = 87 this.table["X"] = 88 this.table["Y"] = 89 this.table["Z"] = 90 this.table["["] = 91 this.table["\\"] = 92 this.table["]"] = 93 this.table["^"] = 94 this.table["_"] = 95 this.table["`"] = 96 this.table["a"] = 97 this.table["b"] = 98 this.table["c"] = 99 this.table["d"] = 100 this.table["e"] = 101 this.table["f"] = 102 this.table["g"] = 103 this.table["h"] = 104 this.table["i"] = 105 this.table["j"] = 106 this.table["k"] = 107 this.table["l"] = 108 this.table["m"] = 109 this.table["n"] = 110 this.table["o"] = 111 this.table["p"] = 112 this.table["q"] = 113 this.table["r"] = 114 this.table["s"] = 115 this.table["t"] = 116 this.table["u"] = 117 this.table["v"] = 118 this.table["w"] = 119 this.table["x"] = 120 this.table["y"] = 121 this.table["z"] = 122 this.table["{"] = 123 this.table["|"] = 124 this.table["}"] = 125 this.table["~"] = 126 this.table["Ç"] = 128 this.table["ü"] = 129 this.table["é"] = 130 this.table["â"] = 131 this.table["ä"] = 132 this.table["à"] = 133 this.table["å"] = 134 this.table["ç"] = 135 this.table["ê"] = 136 this.table["ë"] = 137 this.table["è"] = 138 this.table["ï"] = 139 this.table["î"] = 140 this.table["ì"] = 141 this.table["Ä"] = 142 this.table["Å"] = 143 this.table["É"] = 144 this.table["æ"] = 145 this.table["Æ"] = 146 this.table["ô"] = 147 this.table["ö"] = 148 this.table["ò"] = 149 this.table["û"] = 150 this.table["ù"] = 151 this.table["ÿ"] = 152 this.table["Ö"] = 153 this.table["Ü"] = 154 this.table["ø"] = 155 this.table["£"] = 156 this.table["Ø"] = 157 this.table["×"] = 158 this.table["ƒ"] = 159 this.table["á"] = 160 this.table["í"] = 161 this.table["ó"] = 162 this.table["ú"] = 163 this.table["ñ"] = 164 this.table["Ñ"] = 165 this.table["ª"] = 166 this.table["º"] = 167 this.table["¿"] = 168 this.table["®"] = 169 this.table["¬"] = 170 this.table["½"] = 171 this.table["¼"] = 172 this.table["¡"] = 173 this.table["«"] = 174 this.table["»"] = 175 this.table["░"] = 176 this.table["▒"] = 177 this.table["▓"] = 178 this.table["│"] = 179 this.table["┤"] = 180 this.table["Á"] = 181 this.table["Â"] = 182 this.table["À"] = 183 this.table["©"] = 184 this.table["╣"] = 185 this.table["║"] = 186 this.table["╗"] = 187 this.table["╝"] = 188 this.table["¢"] = 189 this.table["¥"] = 190 this.table["┐"] = 191 this.table["└"] = 192 this.table["┴"] = 193 this.table["┬"] = 194 this.table["├"] = 195 this.table["─"] = 196 this.table["┼"] = 197 this.table["ã"] = 198 this.table["Ã"] = 199 this.table["╚"] = 200 this.table["╔"] = 201 this.table["╩"] = 202 this.table["╦"] = 203 this.table["╠"] = 204 this.table["═"] = 205 this.table["╬"] = 206 this.table["¤"] = 207 this.table["ð"] = 208 this.table["Ð"] = 209 this.table["Ê"] = 210 this.table["Ë"] = 211 this.table["È"] = 212 this.table["ı"] = 213 this.table["Í"] = 214 this.table["Î"] = 215 this.table["Ï"] = 216 this.table["┘"] = 217 this.table["┌"] = 218 this.table["█"] = 219 this.table["▄"] = 220 this.table["¦"] = 221 this.table["Ì"] = 222 this.table["▀"] = 223 this.table["Ó"] = 224 this.table["ß"] = 225 this.table["Ô"] = 226 this.table["Ò"] = 227 this.table["õ"] = 228 this.table["Õ"] = 229 this.table["µ"] = 230 this.table["þ"] = 231 this.table["Þ"] = 232 this.table["Ú"] = 233 this.table["Û"] = 234 this.table["Ù"] = 235 this.table["ý"] = 236 this.table["Ý"] = 237 this.table["¯"] = 238 this.table["´"] = 239 this.table["≡"] = 240 this.table["±"] = 241 this.table["‗"] = 242 this.table["¾"] = 243 this.table["¶"] = 244 this.table["§"] = 245 this.table["÷"] = 246 this.table["¸"] = 247 this.table["°"] = 248 this.table["¨"] = 249 this.table["·"] = 250 this.table["¹"] = 251 this.table["³"] = 252 this.table["²"] = 253 this.table["■"] = 254 for character, value := range this.table { this.inverted_table[value] = character } this.unknown = "■" } func (this *AsciiEncoder) Encode(characters string) *ByteStream { byte_stream := new(ByteStream) byte_stream.Init() for _, character := range characters { value := this.table[string(character)] byte_stream.Append(value) } return byte_stream } func (this *AsciiEncoder) Decode(byte_stream *ByteStream) string { characters := "" for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) characters += this.inverted_table[value] } return characters } func (this *AsciiEncoder) Unknown() string { return this.unknown } ================================================ FILE: golang/uPIMulator/src/abi/encoding/byte_stream.go ================================================ package encoding type ByteStream struct { bytes []uint8 } func (this *ByteStream) Init() { this.bytes = make([]uint8, 0) } func (this *ByteStream) Size() int64 { return int64(len(this.bytes)) } func (this *ByteStream) Get(pos int) uint8 { return this.bytes[pos] } func (this *ByteStream) Set(pos int, value uint8) { this.bytes[pos] = value } func (this *ByteStream) Append(value uint8) { this.bytes = append(this.bytes, value) } func (this *ByteStream) Merge(byte_stream *ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) this.Append(value) } } ================================================ FILE: golang/uPIMulator/src/abi/word/intermediate.go ================================================ package word import ( "uPIMulator/src/abi/encoding" ) type Immediate struct { representation Representation value int64 word *Word } func (this *Immediate) Init(representation Representation, width int, value int64) { this.representation = representation this.value = value this.word = new(Word) this.word.Init(width) this.word.SetValue(value) } func (this *Immediate) Representation() Representation { return this.representation } func (this *Immediate) Width() int { return this.word.Width() } func (this *Immediate) Bit(pos int) bool { return this.word.Bit(pos) } func (this *Immediate) BitSlice(begin int, end int) int64 { return this.word.BitSlice(this.representation, begin, end) } func (this *Immediate) Value() int64 { return this.value } func (this *Immediate) ToByteStream() *encoding.ByteStream { return this.word.ToByteStream() } ================================================ FILE: golang/uPIMulator/src/abi/word/word.go ================================================ package word import ( "errors" "uPIMulator/src/abi/encoding" ) type Representation int const ( UNSIGNED Representation = iota SIGNED ) type Word struct { bits []bool } func (this *Word) Init(width int) { if width <= 0 { err := errors.New("width <= 0") panic(err) } this.bits = make([]bool, width) } func (this *Word) Width() int { return len(this.bits) } func (this *Word) Size() int { if this.Width()%8 != 0 { err := errors.New("width is not a multiple of 8") panic(err) } return this.Width() / 8 } func (this *Word) SignBit() bool { return this.bits[this.Width()-1] } func (this *Word) Bit(pos int) bool { return this.bits[pos] } func (this *Word) SetBit(pos int) { this.bits[pos] = true } func (this *Word) ClearBit(pos int) { this.bits[pos] = false } func (this *Word) BitSlice(representation Representation, begin int, end int) int64 { this.VerifySlice(begin, end) slice_width := end - begin value := int64(0) for i := 0; i < slice_width; i++ { if this.Bit(begin + i) { if representation == SIGNED && i == slice_width-1 { value -= this.Pow2(i) } else { value += this.Pow2(i) } } } return value } func (this *Word) SetBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value >= 0 { this.SetPositiveBitSlice(begin, end, value) } else { this.SetNegativeBitSlice(begin, end, value) } } func (this *Word) Value(representation Representation) int64 { return this.BitSlice(representation, 0, this.Width()) } func (this *Word) SetValue(value int64) { this.SetBitSlice(0, this.Width(), value) } func (this *Word) ToByteStream() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := 0; i < this.Size(); i++ { begin := 8 * i end := begin + 8 value := uint8(this.BitSlice(UNSIGNED, begin, end)) byte_stream.Append(value) } return byte_stream } func (this *Word) FromByteStream(byte_stream *encoding.ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { begin := int(8 * i) end := int(begin + 8) value := int64(byte_stream.Get(int(i))) this.SetBitSlice(begin, end, value) } } func (this *Word) VerifySlice(begin int, end int) { if begin < 0 { err := errors.New("begin < 0") panic(err) } if begin >= end { err := errors.New("begin >= end") panic(err) } if end > this.Width() { err := errors.New("end > width") panic(err) } if end-begin > 64 { err := errors.New("end - begin >= 64") panic(err) } } func (this *Word) Pow2(exponent int) int64 { value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } func (this *Word) SetPositiveBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value < 0 { err := errors.New("value < 0") panic(err) } slice_width := end - begin for i := 0; i < slice_width; i++ { if value%2 == 1 { this.SetBit(begin + i) } else { this.ClearBit(begin + i) } value /= 2 } if value != 0 { err := errors.New("value != 0") panic(err) } } func (this *Word) SetNegativeBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value >= 0 { err := errors.New("value >= 0") panic(err) } this.SetBit(end - 1) if begin+1 < end { slice_width := end - begin value += this.Pow2(slice_width - 1) this.SetPositiveBitSlice(begin, end-1, value) } } ================================================ FILE: golang/uPIMulator/src/assembler/assemblable.go ================================================ package assembler import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type Assemblable interface { Init(command_line_parser *misc.CommandLineParser) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream InputDpuMramHeapPointerName(execution int, dpu_id int) (int64, *encoding.ByteStream) OutputDpuMramHeapPointerName(execution int, dpu_id int) (int64, *encoding.ByteStream) NumExecutions() int } ================================================ FILE: golang/uPIMulator/src/assembler/assembler.go ================================================ package assembler import ( "errors" "fmt" "path/filepath" "uPIMulator/src/assembler/prim" "uPIMulator/src/misc" ) type Assembler struct { bin_dirpath string benchmark string num_channels int num_ranks_per_channel int num_dpus_per_rank int num_dpus int num_tasklets int assemblables map[string]Assemblable } func (this *Assembler) Init(command_line_parser *misc.CommandLineParser) { this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") this.num_channels = int(command_line_parser.IntParameter("num_channels")) this.num_ranks_per_channel = int(command_line_parser.IntParameter("num_ranks_per_channel")) this.num_dpus_per_rank = int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = this.num_channels * this.num_ranks_per_channel * this.num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.assemblables = make(map[string]Assemblable, 0) this.assemblables["BS"] = new(prim.Bs) this.assemblables["GEMV"] = new(prim.Gemv) this.assemblables["HST-L"] = new(prim.HstL) this.assemblables["HST-S"] = new(prim.HstS) this.assemblables["MLP"] = new(prim.Mlp) this.assemblables["RED"] = new(prim.Red) this.assemblables["SCAN-RSS"] = new(prim.ScanRss) this.assemblables["SCAN-SSA"] = new(prim.ScanSsa) this.assemblables["SEL"] = new(prim.Sel) this.assemblables["TRNS"] = new(prim.Trns) this.assemblables["TS"] = new(prim.Ts) this.assemblables["UNI"] = new(prim.Uni) this.assemblables["VA"] = new(prim.Va) if assemblable, found := this.assemblables[this.benchmark]; found { assemblable.Init(command_line_parser) } else { err := errors.New("assemblable is not found") panic(err) } } func (this *Assembler) Assemble() { this.AssembleInputDpuHost() this.AssembleOutputDpuHost() this.AssembleInputDpuMramHeapPointerName() this.AssembleOutputDpuMramHeapPointerName() this.AssembleNumExecutions() } func (this *Assembler) AssembleInputDpuHost() { assemblable := this.assemblables[this.benchmark] for execution := 0; execution < assemblable.NumExecutions(); execution++ { for dpu_id := 0; dpu_id < this.num_dpus; dpu_id++ { input_dpu_host := assemblable.InputDpuHost(execution, dpu_id) for name, byte_stream := range input_dpu_host { filename := fmt.Sprintf("input_%s_%d_%d.bin", name, execution, dpu_id) filepath_ := filepath.Join(this.bin_dirpath, filename) file_dumper := new(misc.FileDumper) file_dumper.Init(filepath_) lines := make([]string, 0) for i := int64(0); i < byte_stream.Size(); i++ { line := fmt.Sprintf("%d", byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper.WriteLines(lines) } } } } func (this *Assembler) AssembleOutputDpuHost() { assemblable := this.assemblables[this.benchmark] for execution := 0; execution < assemblable.NumExecutions(); execution++ { for dpu_id := 0; dpu_id < this.num_dpus; dpu_id++ { output_dpu_host := assemblable.OutputDpuHost(execution, dpu_id) for name, byte_stream := range output_dpu_host { filename := fmt.Sprintf("output_%s_%d_%d.bin", name, execution, dpu_id) filepath_ := filepath.Join(this.bin_dirpath, filename) file_dumper := new(misc.FileDumper) file_dumper.Init(filepath_) lines := make([]string, 0) for i := int64(0); i < byte_stream.Size(); i++ { line := fmt.Sprintf("%d", byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper.WriteLines(lines) } } } } func (this *Assembler) AssembleInputDpuMramHeapPointerName() { assemblable := this.assemblables[this.benchmark] for execution := 0; execution < assemblable.NumExecutions(); execution++ { for dpu_id := 0; dpu_id < this.num_dpus; dpu_id++ { offset, byte_stream := assemblable.InputDpuMramHeapPointerName(execution, dpu_id) filename := fmt.Sprintf( "input_dpu_mram_heap_pointer_name_%d_%d_%d.bin", offset, execution, dpu_id, ) filepath_ := filepath.Join(this.bin_dirpath, filename) file_dumper := new(misc.FileDumper) file_dumper.Init(filepath_) lines := make([]string, 0) for i := int64(0); i < byte_stream.Size(); i++ { line := fmt.Sprintf("%d", byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper.WriteLines(lines) } } } func (this *Assembler) AssembleOutputDpuMramHeapPointerName() { assemblable := this.assemblables[this.benchmark] for execution := 0; execution < assemblable.NumExecutions(); execution++ { for dpu_id := 0; dpu_id < this.num_dpus; dpu_id++ { offset, byte_stream := assemblable.OutputDpuMramHeapPointerName(execution, dpu_id) filename := fmt.Sprintf( "output_dpu_mram_heap_pointer_name_%d_%d_%d.bin", offset, execution, dpu_id, ) filepath_ := filepath.Join(this.bin_dirpath, filename) file_dumper := new(misc.FileDumper) file_dumper.Init(filepath_) lines := make([]string, 0) for i := int64(0); i < byte_stream.Size(); i++ { line := fmt.Sprintf("%d", byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper.WriteLines(lines) } } } func (this *Assembler) AssembleNumExecutions() { assemblable := this.assemblables[this.benchmark] path := filepath.Join(this.bin_dirpath, "num_executions.txt") file_dumper := new(misc.FileDumper) file_dumper.Init(path) line := fmt.Sprintf("%d", assemblable.NumExecutions()) lines := make([]string, 0) lines = append(lines, line) file_dumper.WriteLines(lines) } ================================================ FILE: golang/uPIMulator/src/assembler/prim/bs.go ================================================ package prim import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Bs struct { num_dpus int num_tasklets int num_executions int size int64 input_buffer []int64 query_buffer []int64 results [][]int64 slice_per_dpu int64 query_per_tasklet int64 kernel int64 } func (this *Bs) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 this.size = int64(command_line_parser.DataPrepParams()[0]) num_queries := int64(command_line_parser.DataPrepParams()[0] / 8) if num_queries%int64(this.num_dpus*this.num_tasklets) != 0 { num_queries += int64(this.num_dpus*this.num_tasklets) - num_queries%int64(this.num_dpus*this.num_tasklets) } if num_queries%int64(this.num_dpus*this.num_tasklets) != 0 { err := errors.New("num queries % (num dpus * num tasklets) != 0") panic(err) } this.input_buffer = make([]int64, 0) for i := int64(0); i < this.size; i++ { this.input_buffer = append(this.input_buffer, i+1) } this.query_buffer = make([]int64, 0) for i := int64(0); i < num_queries; i++ { this.query_buffer = append(this.query_buffer, i) } this.results = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.results = append(this.results, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.results[i] = append(this.results[i], 0) } } this.slice_per_dpu = num_queries / int64(this.num_dpus) this.query_per_tasklet = this.slice_per_dpu / int64(this.num_tasklets) for i := 0; i < this.num_dpus; i++ { for j := 0; j < this.num_tasklets; j++ { for k := 0; k < int(this.query_per_tasklet); k++ { is_found := false l := int64(0) r := this.size - 1 for l <= r { m := l + (r-l)/2 if this.input_buffer[m] == this.query_buffer[k+j*int(this.query_per_tasklet)+i*int(this.slice_per_dpu)] { this.results[i][j] = m is_found = true break } if this.input_buffer[m] < this.query_buffer[k+j*int(this.query_per_tasklet)+i*int(this.slice_per_dpu)] { l = m + 1 } else { r = m - 1 } } if !is_found { this.results[i][j] = -1 } } } } this.kernel = 0 } func (this *Bs) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() size_word := new(word.Word) size_word.Init(64) size_word.SetValue(this.size) dpu_input_arguments_byte_stream.Merge(size_word.ToByteStream()) slice_per_dpu_word := new(word.Word) slice_per_dpu_word.Init(64) slice_per_dpu_word.SetValue(this.slice_per_dpu) dpu_input_arguments_byte_stream.Merge(slice_per_dpu_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernel) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Bs) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() for _, result := range this.results[dpu_id] { result_word := new(word.Word) result_word.Init(64) result_word.SetValue(result) dpu_results_byte_stream.Merge(result_word.ToByteStream()) } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *Bs) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, element := range this.input_buffer { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } start_elem := this.slice_per_dpu * int64(dpu_id) end_elem := this.slice_per_dpu * int64(dpu_id+1) for _, element := range this.query_buffer[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Bs) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() return 0, byte_stream } func (this *Bs) NumExecutions() int { return this.num_executions } func (this *Bs) Sum(s []int64) int64 { sum := int64(0) for _, element := range s { sum += element } return sum } func (this *Bs) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/gemv.go ================================================ package prim import ( "errors" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Gemv struct { num_dpus int num_tasklets int num_executions int m_size int64 n_size int64 n_size_pads []int64 nr_rows []int64 max_rows []int64 buffer_a [][]int64 buffer_b []int64 buffer_c [][]int64 } func (this *Gemv) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.m_size = int64(command_line_parser.DataPrepParams()[0]) this.n_size = 64 this.num_executions = 1 if this.m_size%int64(this.num_dpus) != 0 { err := errors.New("m size % num dpus != 0") panic(err) } this.n_size_pads = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if this.n_size%2 == 0 { this.n_size_pads = append(this.n_size_pads, this.n_size) } else { this.n_size_pads = append(this.n_size_pads, this.n_size+1) } } this.nr_rows = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.nr_rows = append(this.nr_rows, this.m_size/int64(this.num_dpus)) } this.max_rows = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if this.nr_rows[i]%2 == 0 { this.max_rows = append(this.max_rows, this.nr_rows[i]) } else { this.max_rows = append(this.max_rows, this.nr_rows[i]+1) } } this.buffer_a = make([][]int64, 0) for i := int64(0); i < this.m_size; i++ { this.buffer_a = append(this.buffer_a, make([]int64, 0)) for j := int64(0); j < this.n_size; j++ { this.buffer_a[i] = append(this.buffer_a[i], int64(rand.Intn(50))) } } this.buffer_b = make([]int64, 0) for i := int64(0); i < this.n_size; i++ { this.buffer_b = append(this.buffer_b, int64(rand.Intn(50))) } this.buffer_c = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.buffer_c = append(this.buffer_c, make([]int64, 0)) } for i := 0; i < this.num_dpus; i++ { start_row := this.nr_rows[i] * int64(i) end_row := this.nr_rows[i] * int64(i+1) this.buffer_c[i] = this.MatMul(this.buffer_a[start_row:end_row], this.buffer_b) } } func (this *Gemv) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() n_size_word := new(word.Word) n_size_word.Init(32) n_size_word.SetValue(this.n_size) dpu_input_arguments_byte_stream.Merge(n_size_word.ToByteStream()) n_size_pad_word := new(word.Word) n_size_pad_word.Init(32) n_size_pad_word.SetValue(this.n_size_pads[dpu_id]) dpu_input_arguments_byte_stream.Merge(n_size_pad_word.ToByteStream()) nr_row_word := new(word.Word) nr_row_word.Init(32) nr_row_word.SetValue(this.nr_rows[dpu_id]) dpu_input_arguments_byte_stream.Merge(nr_row_word.ToByteStream()) max_row_word := new(word.Word) max_row_word.Init(32) max_row_word.SetValue(this.max_rows[dpu_id]) dpu_input_arguments_byte_stream.Merge(max_row_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Gemv) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *Gemv) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_row := this.nr_rows[dpu_id] * int64(dpu_id) end_row := this.nr_rows[dpu_id] * int64(dpu_id+1) for _, row := range this.buffer_a[start_row:end_row] { for _, element := range row { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } for _, element := range this.buffer_b { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Gemv) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_row := this.nr_rows[dpu_id] * int64(dpu_id) end_row := this.nr_rows[dpu_id] * int64(dpu_id+1) offset := int64(0) for i := 0; i < len(this.buffer_a[start_row:end_row]); i++ { for j := 0; j < len(this.buffer_a[i]); j++ { offset += 4 } } for i := 0; i < len(this.buffer_b); i++ { offset += 4 } for _, element := range this.buffer_c[dpu_id] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return offset, byte_stream } func (this *Gemv) NumExecutions() int { return this.num_executions } func (this *Gemv) MatMul(x [][]int64, y []int64) []int64 { results := make([]int64, 0) for i := 0; i < len(x); i++ { results = append(results, 0) } for i := 0; i < len(x); i++ { for j := 0; j < len(y); j++ { results[i] += x[i][j] * y[j] } } return results } ================================================ FILE: golang/uPIMulator/src/assembler/prim/hst_l.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type HstL struct { num_dpus int num_tasklets int num_executions int num_bins int64 input_size_dpu_8bytes int64 buffer_a []int64 buffer_c [][]int64 sizes []int64 dpu_arg_sizes []int64 transfer_size int64 kernel int64 } func (this *HstL) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 size := int64(command_line_parser.DataPrepParams()[0]) this.num_bins = 256 elem_size := int64(4) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } var input_size_8bytes int64 if (input_size*elem_size)%8 == 0 { input_size_8bytes = input_size } else { input_size_8bytes = int64(math.Ceil(float64(input_size)/float64(8)) * 8) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if (input_size_dpu*elem_size)%8 == 0 { this.input_size_dpu_8bytes = input_size_dpu } else { this.input_size_dpu_8bytes = int64(math.Ceil(float64(input_size_dpu)/float64(8)) * 8) } this.buffer_a = make([]int64, 0) for i := int64(0); i < input_size; i++ { this.buffer_a = append(this.buffer_a, int64(rand.Intn(4096))) } depth := int64(12) this.buffer_c = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.buffer_c = append(this.buffer_c, make([]int64, 0)) for j := int64(0); j < this.num_bins; j++ { this.buffer_c[i] = append(this.buffer_c[i], 0) } } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_8bytes * int64(i) end_elem := this.input_size_dpu_8bytes * int64(i+1) for _, elem := range this.buffer_a[start_elem:end_elem] { this.buffer_c[i][(elem*this.num_bins)>>depth] += 1 } } this.dpu_arg_sizes = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if i != this.num_dpus-1 { this.dpu_arg_sizes = append(this.dpu_arg_sizes, this.input_size_dpu_8bytes*elem_size) } else { this.dpu_arg_sizes = append(this.dpu_arg_sizes, (input_size_8bytes-this.input_size_dpu_8bytes*int64(this.num_dpus-1))*elem_size) } } this.transfer_size = this.input_size_dpu_8bytes * elem_size this.kernel = 0 } func (this *HstL) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) transfer_size_word := new(word.Word) transfer_size_word.Init(32) transfer_size_word.SetValue(this.transfer_size) dpu_input_arguments_byte_stream.Merge(transfer_size_word.ToByteStream()) num_bins_word := new(word.Word) num_bins_word.Init(32) num_bins_word.SetValue(this.num_bins) dpu_input_arguments_byte_stream.Merge(num_bins_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernel) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *HstL) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *HstL) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_8bytes * int64(dpu_id) end_elem := this.input_size_dpu_8bytes * int64(dpu_id+1) for _, element := range this.buffer_a[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *HstL) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, element := range this.buffer_c[dpu_id] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return this.input_size_dpu_8bytes * 4, byte_stream } func (this *HstL) NumExecutions() int { return this.num_executions } func (this *HstL) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/hst_s.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type HstS struct { num_dpus int num_tasklets int num_executions int num_bins int64 input_size_dpu_8bytes int64 buffer_a []int64 buffer_c [][]int64 sizes []int64 dpu_arg_sizes []int64 transfer_size int64 kernel int64 } func (this *HstS) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 size := int64(command_line_parser.DataPrepParams()[0]) this.num_bins = 256 elem_size := int64(4) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } var input_size_8bytes int64 if (input_size*elem_size)%8 == 0 { input_size_8bytes = input_size } else { input_size_8bytes = int64(math.Ceil(float64(input_size)/float64(8)) * 8) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if (input_size_dpu*elem_size)%8 == 0 { this.input_size_dpu_8bytes = input_size_dpu } else { this.input_size_dpu_8bytes = int64(math.Ceil(float64(input_size_dpu)/float64(8)) * 8) } this.buffer_a = make([]int64, 0) for i := int64(0); i < input_size; i++ { this.buffer_a = append(this.buffer_a, int64(rand.Intn(4096))) } depth := int64(12) this.buffer_c = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.buffer_c = append(this.buffer_c, make([]int64, 0)) for j := int64(0); j < this.num_bins; j++ { this.buffer_c[i] = append(this.buffer_c[i], 0) } } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_8bytes * int64(i) end_elem := this.input_size_dpu_8bytes * int64(i+1) for _, elem := range this.buffer_a[start_elem:end_elem] { this.buffer_c[i][(elem*this.num_bins)>>depth] += 1 } } this.dpu_arg_sizes = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if i != this.num_dpus-1 { this.dpu_arg_sizes = append(this.dpu_arg_sizes, this.input_size_dpu_8bytes*elem_size) } else { this.dpu_arg_sizes = append(this.dpu_arg_sizes, (input_size_8bytes-this.input_size_dpu_8bytes*int64(this.num_dpus-1))*elem_size) } } this.transfer_size = this.input_size_dpu_8bytes * elem_size this.kernel = 0 } func (this *HstS) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) transfer_size_word := new(word.Word) transfer_size_word.Init(32) transfer_size_word.SetValue(this.transfer_size) dpu_input_arguments_byte_stream.Merge(transfer_size_word.ToByteStream()) num_bins_word := new(word.Word) num_bins_word.Init(32) num_bins_word.SetValue(this.num_bins) dpu_input_arguments_byte_stream.Merge(num_bins_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernel) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *HstS) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *HstS) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_8bytes * int64(dpu_id) end_elem := this.input_size_dpu_8bytes * int64(dpu_id+1) for _, element := range this.buffer_a[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *HstS) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, element := range this.buffer_c[dpu_id] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return this.input_size_dpu_8bytes * 4, byte_stream } func (this *HstS) NumExecutions() int { return this.num_executions } func (this *HstS) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/mlp.go ================================================ package prim import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Mlp struct { num_dpus int num_tasklets int num_executions int m_size int64 n_size int64 num_layers int64 n_size_pads []int64 nr_rows []int64 max_rows []int64 buffer_a [][][]int64 buffer_b [][]int64 buffer_c [][][]int64 } func (this *Mlp) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.m_size = int64(command_line_parser.DataPrepParams()[0]) this.n_size = int64(command_line_parser.DataPrepParams()[0]) this.num_layers = 3 this.num_executions = int(this.num_layers) if this.m_size%int64(this.num_dpus) != 0 { err := errors.New("m size % num dpus != 0") panic(err) } this.n_size_pads = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if this.n_size%2 == 0 { this.n_size_pads = append(this.n_size_pads, this.n_size) } else { this.n_size_pads = append(this.n_size_pads, this.n_size+1) } } this.nr_rows = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.nr_rows = append(this.nr_rows, this.m_size/int64(this.num_dpus)) } this.max_rows = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { if this.nr_rows[i]%2 == 0 { this.max_rows = append(this.max_rows, this.nr_rows[i]) } else { this.max_rows = append(this.max_rows, this.nr_rows[i]+1) } } this.buffer_a = make([][][]int64, 0) for i := int64(0); i < this.num_layers; i++ { this.buffer_a = append(this.buffer_a, make([][]int64, 0)) for j := int64(0); j < this.m_size; j++ { this.buffer_a[i] = append(this.buffer_a[i], make([]int64, 0)) for k := int64(0); k < this.n_size; k++ { if k%100 < 98 { this.buffer_a[i][j] = append(this.buffer_a[i][j], 0) } else { this.buffer_a[i][j] = append(this.buffer_a[i][j], (i+k)%2) } } } } this.buffer_b = make([][]int64, 0) for i := int64(0); i < this.num_layers; i++ { this.buffer_b = append(this.buffer_b, make([]int64, 0)) for j := int64(0); j < this.n_size; j++ { if j%50 < 48 { this.buffer_b[i] = append(this.buffer_b[i], 0) } else { this.buffer_b[i] = append(this.buffer_b[i], j%2) } } } this.buffer_c = make([][][]int64, 0) for i := int64(0); i < this.num_layers; i++ { this.buffer_c = append(this.buffer_c, make([][]int64, 0)) for j := 0; j < this.num_dpus; j++ { this.buffer_c[i] = append(this.buffer_c[i], make([]int64, 0)) } } for i := int64(0); i < this.num_layers; i++ { for j := 0; j < this.num_dpus; j++ { start_row := this.nr_rows[j] * int64(j) end_row := this.nr_rows[j] * int64(j+1) this.buffer_c[i][j] = this.MatMul(this.buffer_a[i][start_row:end_row], this.buffer_b[i]) for k := 0; k < len(this.buffer_c[i][j]); k++ { if this.buffer_c[i][j][k] < 0 { this.buffer_c[i][j][k] = 0 } } if i < this.num_layers-1 { if len(this.buffer_b[i+1][start_row:end_row]) != len(this.buffer_c[i][j]) { err := errors.New("buffer b [i+1][start_row:end_row]'s length != buffer c [i][j]'s length") panic(err) } for k, element := range this.buffer_c[i][j] { this.buffer_b[i+1][k] = element } } } } } func (this *Mlp) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() n_size_word := new(word.Word) n_size_word.Init(32) n_size_word.SetValue(this.n_size) dpu_input_arguments_byte_stream.Merge(n_size_word.ToByteStream()) n_size_pad_word := new(word.Word) n_size_pad_word.Init(32) n_size_pad_word.SetValue(this.n_size_pads[dpu_id]) dpu_input_arguments_byte_stream.Merge(n_size_pad_word.ToByteStream()) nr_row_word := new(word.Word) nr_row_word.Init(32) nr_row_word.SetValue(this.nr_rows[dpu_id]) dpu_input_arguments_byte_stream.Merge(nr_row_word.ToByteStream()) max_row_word := new(word.Word) max_row_word.Init(32) max_row_word.SetValue(this.max_rows[dpu_id]) dpu_input_arguments_byte_stream.Merge(max_row_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Mlp) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *Mlp) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_row := this.nr_rows[dpu_id] * int64(dpu_id) end_row := this.nr_rows[dpu_id] * int64(dpu_id+1) for _, row := range this.buffer_a[execution][start_row:end_row] { for _, element := range row { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } for _, element := range this.buffer_b[execution] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Mlp) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_row := this.nr_rows[dpu_id] * int64(dpu_id) end_row := this.nr_rows[dpu_id] * int64(dpu_id+1) offset := int64(0) for i := 0; i < len(this.buffer_a[execution][start_row:end_row]); i++ { for j := 0; j < len(this.buffer_a[execution][i]); j++ { offset += 4 } } for i := 0; i < len(this.buffer_b[execution]); i++ { offset += 4 } for _, element := range this.buffer_c[execution][dpu_id] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return offset, byte_stream } func (this *Mlp) NumExecutions() int { return this.num_executions } func (this *Mlp) MatMul(x [][]int64, y []int64) []int64 { results := make([]int64, 0) for i := 0; i < len(x); i++ { results = append(results, 0) } for i := 0; i < len(x); i++ { for j := 0; j < len(y); j++ { results[i] += x[i][j] * y[j] } } return results } ================================================ FILE: golang/uPIMulator/src/assembler/prim/red.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Red struct { num_dpus int num_tasklets int num_executions int input_size_dpu_8bytes int64 buffer_a []int64 counts []int64 dpu_arg_sizes []int64 kernels []int64 input_t_counts []int64 cycles [][]int64 t_counts [][]int64 } func (this *Red) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(8) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } var input_size_8bytes int64 if (input_size*elem_size)%8 == 0 { input_size_8bytes = input_size } else { input_size_8bytes = int64(math.Ceil(float64(input_size)/float64(8)) * 8) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if (input_size_dpu*elem_size)%8 == 0 { this.input_size_dpu_8bytes = input_size_dpu } else { this.input_size_dpu_8bytes = int64(math.Ceil(float64(input_size_dpu)/float64(8)) * 8) } this.buffer_a = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_8bytes*int64(this.num_dpus); i++ { a := int64(rand.Intn(this.Pow2(31))) this.buffer_a = append(this.buffer_a, a) } this.counts = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.counts = append(this.counts, 0) } this.dpu_arg_sizes = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.dpu_arg_sizes = append(this.dpu_arg_sizes, 0) } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_8bytes * int64(i) var end_elem int64 if i != this.num_dpus-1 { end_elem = this.input_size_dpu_8bytes * int64(i+1) } else { end_elem = input_size } this.counts[i] = this.Sum(this.buffer_a[start_elem:end_elem]) if i != this.num_dpus-1 { this.dpu_arg_sizes[i] = this.input_size_dpu_8bytes * elem_size } else { this.dpu_arg_sizes[i] = (input_size_8bytes - this.input_size_dpu_8bytes*int64(this.num_dpus-1)) * elem_size } } this.kernels = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.kernels = append(this.kernels, 0) } this.input_t_counts = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.input_t_counts = append(this.input_t_counts, 0) } this.cycles = make([][]int64, 0) this.t_counts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.cycles = append(this.cycles, make([]int64, 0)) this.t_counts = append(this.t_counts, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.cycles[i] = append(this.cycles[i], 0) if j == 0 { this.t_counts[i] = append(this.t_counts[i], this.counts[i]) } else { this.t_counts[i] = append(this.t_counts[i], 0) } } } } func (this *Red) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[dpu_id]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) input_t_count_word := new(word.Word) input_t_count_word.Init(32) input_t_count_word.SetValue(this.input_t_counts[dpu_id]) dpu_input_arguments_byte_stream.Merge(input_t_count_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Red) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() if len(this.cycles[dpu_id]) != len(this.t_counts[dpu_id]) { err := errors.New("cycles' length != t counts' length") panic(err) } for i := 0; i < len(this.cycles[dpu_id]); i++ { cycle_word := new(word.Word) cycle_word.Init(64) cycle_word.SetValue(this.cycles[dpu_id][i]) dpu_results_byte_stream.Merge(cycle_word.ToByteStream()) t_count_word := new(word.Word) t_count_word.Init(64) t_count_word.SetValue(this.t_counts[dpu_id][i]) dpu_results_byte_stream.Merge(t_count_word.ToByteStream()) } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *Red) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_8bytes * int64(dpu_id) for i := int64(0); i < this.input_size_dpu_8bytes; i++ { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(this.buffer_a[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Red) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() return 0, byte_stream } func (this *Red) NumExecutions() int { return this.num_executions } func (this *Red) Sum(s []int64) int64 { sum := int64(0) for _, element := range s { sum += element } return sum } func (this *Red) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/scan_rss.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type ScanRss struct { num_dpus int num_tasklets int num_executions int input_size_dpu_round int64 buffer_a []int64 buffer_c []int64 last_result_values []int64 result_t_counts [][]int64 dpu_arg_size int64 kernels []int64 t_counts [][]int64 } func (this *ScanRss) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 2 size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(8) regs := int64(128) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if input_size_dpu%(int64(this.num_tasklets)*regs) == 0 { this.input_size_dpu_round = input_size_dpu } else { this.input_size_dpu_round = int64(math.Ceil(float64(input_size_dpu)/float64(int64(this.num_tasklets)*regs))) * int64(this.num_tasklets) * regs } this.buffer_a = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var a int64 if i < input_size { a = int64(rand.Intn(100)) } else { a = 0 } this.buffer_a = append(this.buffer_a, a) } this.buffer_c = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var c int64 if i == 0 { c = this.buffer_a[i] } else { c = this.buffer_c[i-1] + this.buffer_a[i] } this.buffer_c = append(this.buffer_c, c) } this.last_result_values = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.last_result_values = append(this.last_result_values, 0) } this.result_t_counts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.result_t_counts = append(this.result_t_counts, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.result_t_counts[i] = append(this.result_t_counts[i], 0) } } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_round * int64(i) end_elem := this.input_size_dpu_round * int64(i+1) this.last_result_values[i] = this.Sum1D(this.buffer_a[start_elem:end_elem]) this.result_t_counts[i][0] = this.last_result_values[i] } this.dpu_arg_size = this.input_size_dpu_round * elem_size this.kernels = []int64{0, 1} this.t_counts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.t_counts = append(this.t_counts, make([]int64, 0)) for j := 0; j < 2; j++ { if i == 0 { this.t_counts[i] = []int64{ 0, 0, } } else { this.t_counts[i] = []int64{ 0, this.Sum2D(this.result_t_counts[0:i]), } } } } } func (this *ScanRss) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_size) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[execution]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) t_count_word := new(word.Word) t_count_word.Init(64) t_count_word.SetValue(this.t_counts[dpu_id][execution]) dpu_input_arguments_byte_stream.Merge(t_count_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *ScanRss) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() if execution == 0 { for _, result_t_count := range this.result_t_counts[dpu_id] { result_t_count_word := new(word.Word) result_t_count_word.Init(64) result_t_count_word.SetValue(result_t_count) dpu_results_byte_stream.Merge(result_t_count_word.ToByteStream()) } } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *ScanRss) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution == 0 { start_elem := this.input_size_dpu_round * int64(dpu_id) end_elem := this.input_size_dpu_round * int64(dpu_id+1) for _, element := range this.buffer_a[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } return 0, byte_stream } func (this *ScanRss) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution == this.num_executions-1 { start_elem := this.input_size_dpu_round * int64(dpu_id) end_elem := this.input_size_dpu_round * int64(dpu_id+1) for _, element := range this.buffer_c[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } return int64(this.input_size_dpu_round * 8), byte_stream } func (this *ScanRss) NumExecutions() int { return this.num_executions } func (this *ScanRss) Sum1D(s []int64) int64 { sum := int64(0) for _, element := range s { sum += element } return sum } func (this *ScanRss) Sum2D(s [][]int64) int64 { sum := int64(0) for _, elements := range s { for _, element := range elements { sum += element } } return sum } func (this *ScanRss) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/scan_ssa.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type ScanSsa struct { num_dpus int num_tasklets int num_executions int input_size_dpu_round int64 buffer_a []int64 buffer_c []int64 last_result_values []int64 result_t_counts [][]int64 dpu_arg_size int64 kernels []int64 t_counts [][]int64 } func (this *ScanSsa) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 2 size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(8) regs := int64(128) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if input_size_dpu%(int64(this.num_tasklets)*regs) == 0 { this.input_size_dpu_round = input_size_dpu } else { this.input_size_dpu_round = int64(math.Ceil(float64(input_size_dpu)/float64(int64(this.num_tasklets)*regs))) * int64(this.num_tasklets) * regs } this.buffer_a = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var a int64 if i < input_size { a = int64(rand.Intn(100)) } else { a = 0 } this.buffer_a = append(this.buffer_a, a) } this.buffer_c = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var c int64 if i == 0 { c = this.buffer_a[i] } else { c = this.buffer_c[i-1] + this.buffer_a[i] } this.buffer_c = append(this.buffer_c, c) } this.last_result_values = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.last_result_values = append(this.last_result_values, 0) } this.result_t_counts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.result_t_counts = append(this.result_t_counts, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.result_t_counts[i] = append(this.result_t_counts[i], 0) } } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_round * int64(i) end_elem := this.input_size_dpu_round * int64(i+1) this.last_result_values[i] = this.Sum1D(this.buffer_a[start_elem:end_elem]) this.result_t_counts[i][this.num_tasklets-1] = this.last_result_values[i] } this.dpu_arg_size = this.input_size_dpu_round * elem_size this.kernels = []int64{0, 1} this.t_counts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.t_counts = append(this.t_counts, make([]int64, 0)) for j := 0; j < 2; j++ { if i == 0 { this.t_counts[i] = []int64{ 0, 0, } } else { this.t_counts[i] = []int64{ 0, this.Sum2D(this.result_t_counts[0:i]), } } } } } func (this *ScanSsa) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_size) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[execution]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) t_count_word := new(word.Word) t_count_word.Init(64) t_count_word.SetValue(this.t_counts[dpu_id][execution]) dpu_input_arguments_byte_stream.Merge(t_count_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *ScanSsa) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() if execution == 0 { for _, result_t_count := range this.result_t_counts[dpu_id] { result_t_count_word := new(word.Word) result_t_count_word.Init(64) result_t_count_word.SetValue(result_t_count) dpu_results_byte_stream.Merge(result_t_count_word.ToByteStream()) } } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *ScanSsa) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution == 0 { start_elem := this.input_size_dpu_round * int64(dpu_id) end_elem := this.input_size_dpu_round * int64(dpu_id+1) for _, element := range this.buffer_a[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } return 0, byte_stream } func (this *ScanSsa) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution == this.num_executions-1 { start_elem := this.input_size_dpu_round * int64(dpu_id) end_elem := this.input_size_dpu_round * int64(dpu_id+1) for _, element := range this.buffer_c[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } return int64(this.input_size_dpu_round * 8), byte_stream } func (this *ScanSsa) NumExecutions() int { return this.num_executions } func (this *ScanSsa) Sum1D(s []int64) int64 { sum := int64(0) for _, element := range s { sum += element } return sum } func (this *ScanSsa) Sum2D(s [][]int64) int64 { sum := int64(0) for _, elements := range s { for _, element := range elements { sum += element } } return sum } func (this *ScanSsa) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/assembler/prim/sel.go ================================================ package prim import ( "errors" "math" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Sel struct { num_dpus int num_tasklets int num_executions int buffer_a []int64 buffer_c [][]int64 input_size_dpu_round int64 pos []int64 dpu_arg_sizes []int64 kernels []int64 results [][]int64 } func (this *Sel) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(8) regs := int64(128) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if input_size_dpu%(int64(this.num_tasklets)*regs) == 0 { this.input_size_dpu_round = input_size_dpu } else { this.input_size_dpu_round = int64(math.Ceil(float64(input_size_dpu)/float64(int64(this.num_tasklets)*regs))) * int64(this.num_tasklets) * regs } this.buffer_a = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var a int64 if i < input_size { a = i + 1 } else { a = 0 } this.buffer_a = append(this.buffer_a, a) } this.buffer_c = make([][]int64, 0) this.pos = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.buffer_c = append(this.buffer_c, make([]int64, 0)) start_elem := this.input_size_dpu_round * int64(i) end_elem := this.input_size_dpu_round * int64(i+1) for _, a := range this.buffer_a[start_elem:end_elem] { if a%2 != 0 { this.buffer_c[i] = append(this.buffer_c[i], a) } } this.pos = append(this.pos, int64(len(this.buffer_c[i]))) for int64(len(this.buffer_c[i])) < this.input_size_dpu_round { this.buffer_c[i] = append(this.buffer_c[i], 0) } } this.dpu_arg_sizes = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.dpu_arg_sizes = append(this.dpu_arg_sizes, this.input_size_dpu_round*elem_size) } this.kernels = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.kernels = append(this.kernels, 0) } this.results = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.results = append(this.results, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { if j != this.num_tasklets-1 { this.results[i] = append(this.results[i], 0) } else { this.results[i] = append(this.results[i], this.pos[i]) } } } } func (this *Sel) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() dpu_arg_size_word := new(word.Word) dpu_arg_size_word.Init(32) dpu_arg_size_word.SetValue(this.dpu_arg_sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(dpu_arg_size_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[dpu_id]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Sel) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() for _, result := range this.results[dpu_id] { result_word := new(word.Word) result_word.Init(32) result_word.SetValue(result) dpu_results_byte_stream.Merge(result_word.ToByteStream()) } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *Sel) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_round * int64(dpu_id) for i := int64(0); i < this.input_size_dpu_round; i++ { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(this.buffer_a[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Sel) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for i, element := range this.buffer_c[dpu_id] { if int64(i) >= this.pos[dpu_id] { break } element_word := new(word.Word) element_word.Init(64) element_word.SetValue(int64(element)) byte_stream.Merge(element_word.ToByteStream()) } return this.input_size_dpu_round * 8, byte_stream } func (this *Sel) NumExecutions() int { return this.num_executions } ================================================ FILE: golang/uPIMulator/src/assembler/prim/trns.go ================================================ package prim import ( "errors" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Trns struct { num_dpus int num_tasklets int num_executions int num_active_dpus_at_begining int64 n int64 M int64 m int64 N int64 buffer_a [][][]int64 buffer_c [][][]int64 dones []int64 kernels []int64 } func (this *Trns) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) //NOTE(dongjae.lee@kaist.ac.kr): different parameter given if single dpu is simulated if num_channels == 1 && num_ranks_per_channel == 1 && num_dpus_per_rank == 1 { this.N = 1 this.n = 4 this.M = int64(command_line_parser.DataPrepParams()[0]) this.m = 16 } else { this.N = 64 this.n = 8 this.M = int64(command_line_parser.DataPrepParams()[0]) this.m = 4 } is_strong_scaling := true if !is_strong_scaling { this.N *= int64(this.num_dpus) } if this.N > int64(this.num_dpus) { this.num_active_dpus_at_begining = int64(this.num_dpus) } else { this.num_active_dpus_at_begining = this.N } if is_strong_scaling { this.num_executions = int(2 * (this.N / this.num_active_dpus_at_begining)) } else { this.num_executions = int(2 * this.N) } this.buffer_a = make([][][]int64, 0) for i := int64(0); i < this.N; i++ { this.buffer_a = append(this.buffer_a, make([][]int64, 0)) for j := int64(0); j < this.M*this.m; j++ { this.buffer_a[i] = append(this.buffer_a[i], make([]int64, 0)) for k := int64(0); k < this.n; k++ { this.buffer_a[i][j] = append(this.buffer_a[i][j], int64(rand.Intn(100))) } } } this.dones = make([]int64, 0) if (this.M*this.n)/8 == 0 { for i := 0; i < 8; i++ { this.dones = append(this.dones, 0) } } else { for i := int64(0); i < this.M*this.n; i++ { this.dones = append(this.dones, 0) } } this.buffer_c = make([][][]int64, 0) for i := int64(0); i < this.N; i++ { this.buffer_c = append(this.buffer_c, this.Transpose(this.buffer_a[i])) } this.kernels = []int64{0, 1} } func (this *Trns) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() m_word := new(word.Word) m_word.Init(32) m_word.SetValue(this.m) dpu_input_arguments_byte_stream.Merge(m_word.ToByteStream()) n_word := new(word.Word) n_word.Init(32) n_word.SetValue(this.n) dpu_input_arguments_byte_stream.Merge(n_word.ToByteStream()) M_word := new(word.Word) M_word.Init(32) M_word.SetValue(this.M) dpu_input_arguments_byte_stream.Merge(M_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[execution%2]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Trns) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *Trns) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution%2 == 0 { for _, row := range this.buffer_a[(this.num_active_dpus_at_begining*(int64(execution)/2))+int64(dpu_id)] { for _, element := range row { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } for _, done := range this.dones { done_word := new(word.Word) done_word.Init(8) done_word.SetValue(done) byte_stream.Merge(done_word.ToByteStream()) } } return 0, byte_stream } func (this *Trns) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() if execution%2 == 1 { for _, row := range this.buffer_c[(this.num_active_dpus_at_begining*(int64(execution)/2))+int64(dpu_id)] { for _, element := range row { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } } } return 0, byte_stream } func (this *Trns) NumExecutions() int { return this.num_executions } func (this *Trns) Transpose(s [][]int64) [][]int64 { xl := len(s[0]) yl := len(s) result := make([][]int64, xl) for i, _ := range result { result[i] = make([]int64, yl) } for i := 0; i < xl; i++ { for j := 0; j < yl; j++ { result[i][j] = s[j][i] } } return result } ================================================ FILE: golang/uPIMulator/src/assembler/prim/ts.go ================================================ package prim import ( "errors" "math" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Ts struct { num_dpus int num_tasklets int num_executions int ts_size int64 query_length int64 query_mean int64 query_std int64 slice_per_dpu int64 exclusion_zone int64 kernel int64 min_vals [][]int64 min_idxs [][]int64 max_vals [][]int64 max_idxs [][]int64 query_buffer []int64 t_series_buffer []int64 amean_buffer []int64 asigma_buffer []int64 block_size int64 dotpip int64 elem_size int64 } func (this *Ts) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 this.ts_size = int64(command_line_parser.DataPrepParams()[0]) this.query_length = 64 if this.ts_size%(int64(this.num_dpus)*int64(this.num_tasklets)*this.query_length) != 0 { this.ts_size += int64(this.num_dpus)*int64(this.num_tasklets)*this.query_length - this.ts_size%(int64(this.num_dpus)*int64(this.num_tasklets)*this.query_length) } this.t_series_buffer = make([]int64, 0) for i := int64(0); i < this.ts_size; i++ { this.t_series_buffer = append(this.t_series_buffer, i%127) } this.query_buffer = make([]int64, 0) for i := int64(0); i < this.query_length; i++ { this.query_buffer = append(this.query_buffer, i%127) } this.asigma_buffer = make([]int64, 0) for i := int64(0); i < this.ts_size; i++ { this.asigma_buffer = append(this.asigma_buffer, 0) } this.amean_buffer = make([]int64, 0) for i := int64(0); i < this.ts_size; i++ { this.amean_buffer = append(this.amean_buffer, 0) } acum_sum_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size; i++ { if i == 0 { acum_sum_buffer = append(acum_sum_buffer, this.t_series_buffer[i]) } else { acum_sum_buffer = append(acum_sum_buffer, this.t_series_buffer[i]+acum_sum_buffer[i-1]) } } asqcum_sum_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size; i++ { if i == 0 { asqcum_sum_buffer = append( asqcum_sum_buffer, this.t_series_buffer[i]*this.t_series_buffer[i], ) } else { asqcum_sum_buffer = append(asqcum_sum_buffer, this.t_series_buffer[i]*this.t_series_buffer[i]+asqcum_sum_buffer[i-1]) } } asum_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length+1; i++ { if i == 0 { asum_buffer = append(asum_buffer, acum_sum_buffer[this.query_length-i-1]) } else { asum_buffer = append(asum_buffer, acum_sum_buffer[this.query_length+i-1]-acum_sum_buffer[i-1]) } } asum_sq_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length+1; i++ { if i == 0 { asum_sq_buffer = append(asum_sq_buffer, asqcum_sum_buffer[this.query_length+i-1]) } else { asum_sq_buffer = append(asum_sq_buffer, asqcum_sum_buffer[this.query_length+i-1]-asqcum_sum_buffer[i-1]) } } amean_temp_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length; i++ { amean_temp_buffer = append(amean_temp_buffer, asum_buffer[i]/this.query_length) } asigma_sq_buffer := make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length; i++ { asigma_sq_buffer = append( asigma_sq_buffer, asum_sq_buffer[i]/this.query_length-this.amean_buffer[i]*this.amean_buffer[i], ) } this.asigma_buffer = make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length; i++ { this.asigma_buffer = append( this.asigma_buffer, int64(math.Sqrt(float64(asigma_sq_buffer[i]))), ) } this.amean_buffer = make([]int64, 0) for i := int64(0); i < this.ts_size-this.query_length; i++ { this.amean_buffer = append(this.amean_buffer, amean_temp_buffer[i]) } for i := int64(0); i < this.query_length; i++ { this.t_series_buffer = append(this.t_series_buffer, 0) } for i := int64(0); i < this.query_length*2; i++ { this.asigma_buffer = append(this.asigma_buffer, 0) this.amean_buffer = append(this.amean_buffer, 0) } if len(this.t_series_buffer) != len(this.amean_buffer) { err := errors.New("t series buffer's length != amean buffer's length") panic(err) } this.query_mean = 0 for i := int64(0); i < this.query_length; i++ { this.query_mean += this.query_buffer[i] } this.query_mean /= this.query_length query_variance := int64(0) for i := int64(0); i < this.query_length; i++ { query_variance += (this.query_buffer[i] - this.query_mean) * (this.query_buffer[i] - this.query_mean) } query_variance /= this.query_length query_std_dev := math.Sqrt(float64(query_variance)) this.query_std = int64(query_std_dev) this.slice_per_dpu = this.ts_size / int64(this.num_dpus) this.min_vals = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.min_vals = append(this.min_vals, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.min_vals[i] = append(this.min_vals[i], 0x7FFFFFFF) } } this.min_idxs = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.min_idxs = append(this.min_idxs, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.min_idxs[i] = append(this.min_idxs[i], 0) } } this.max_vals = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.max_vals = append(this.max_vals, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.max_vals[i] = append(this.max_vals[i], 0) } } this.max_idxs = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.max_idxs = append(this.max_idxs, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { this.max_idxs[i] = append(this.max_idxs[i], 0) } } my_start_elems := make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { my_start_elems = append(my_start_elems, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { my_start_elems[i] = append( my_start_elems[i], this.slice_per_dpu*int64(i)+int64(j)*(this.slice_per_dpu/int64(this.num_tasklets)), ) } } my_end_elems := make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { my_end_elems = append(my_end_elems, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { my_end_elems[i] = append( my_end_elems[i], my_start_elems[i][j]+(this.slice_per_dpu/int64(this.num_tasklets))-1, ) } } for i := 0; i < this.num_dpus; i++ { for j := 0; j < this.num_tasklets; j++ { if my_end_elems[i][j] > this.slice_per_dpu*int64(i+1)-this.query_length { my_end_elems[i][j] = this.slice_per_dpu*int64(i+1) - this.query_length } } } this.block_size = 256 this.elem_size = 4 increment := this.block_size / this.elem_size this.dotpip = this.block_size / this.elem_size iter := int64(0) for i := 0; i < this.num_dpus; i++ { iter = 0 for j := 0; j < this.num_tasklets; j++ { for k := my_start_elems[i][j]; k < my_end_elems[i][j]; k += increment { cache_dotprods := make([]int64, 0) for l := int64(0); l < this.dotpip; l++ { cache_dotprods = append(cache_dotprods, 0) } for l := int64(0); l < this.query_length/increment; l++ { cache_dotprods = this.DotProduct(this.t_series_buffer[k:k+increment], this.t_series_buffer[k+increment:k+2*increment], this.query_buffer[l*increment:(l+1)*increment], cache_dotprods, ) } for l := int64(0); l < increment; l++ { distance := 2 * (this.query_length - (cache_dotprods[l]-this.query_length*this.amean_buffer[l+iter*increment+int64(i)*this.slice_per_dpu]*this.query_mean)/(this.asigma_buffer[l+iter*increment+int64(i)*this.slice_per_dpu]*this.query_std)) if distance < this.min_vals[i][j] { this.min_vals[i][j] = distance this.min_idxs[i][j] = int64(k) + l - (int64(i) * this.slice_per_dpu) } } iter++ } } } this.exclusion_zone = 0 this.kernel = 0 } func (this *Ts) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() ts_size_word := new(word.Word) ts_size_word.Init(32) ts_size_word.SetValue(this.ts_size) dpu_input_arguments_byte_stream.Merge(ts_size_word.ToByteStream()) query_length_word := new(word.Word) query_length_word.Init(32) query_length_word.SetValue(this.query_length) dpu_input_arguments_byte_stream.Merge(query_length_word.ToByteStream()) query_mean_word := new(word.Word) query_mean_word.Init(32) query_mean_word.SetValue(this.query_mean) dpu_input_arguments_byte_stream.Merge(query_mean_word.ToByteStream()) query_std_word := new(word.Word) query_std_word.Init(32) query_std_word.SetValue(this.query_std) dpu_input_arguments_byte_stream.Merge(query_std_word.ToByteStream()) slice_per_dpu_word := new(word.Word) slice_per_dpu_word.Init(32) slice_per_dpu_word.SetValue(this.slice_per_dpu) dpu_input_arguments_byte_stream.Merge(slice_per_dpu_word.ToByteStream()) exclusion_zone_word := new(word.Word) exclusion_zone_word.Init(32) exclusion_zone_word.SetValue(this.exclusion_zone) dpu_input_arguments_byte_stream.Merge(exclusion_zone_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernel) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Ts) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() for i := 0; i < this.num_tasklets; i++ { min_val_word := new(word.Word) min_val_word.Init(32) min_val_word.SetValue(this.min_vals[dpu_id][i]) dpu_results_byte_stream.Merge(min_val_word.ToByteStream()) min_idx_word := new(word.Word) min_idx_word.Init(32) min_idx_word.SetValue(this.min_idxs[dpu_id][i]) dpu_results_byte_stream.Merge(min_idx_word.ToByteStream()) max_val_word := new(word.Word) max_val_word.Init(32) max_val_word.SetValue(this.max_vals[dpu_id][i]) dpu_results_byte_stream.Merge(max_val_word.ToByteStream()) max_idx_word := new(word.Word) max_idx_word.Init(32) max_idx_word.SetValue(this.max_idxs[dpu_id][i]) dpu_results_byte_stream.Merge(max_idx_word.ToByteStream()) } dpu_results := make(map[string]*encoding.ByteStream, 0) dpu_results["DPU_RESULTS"] = dpu_results_byte_stream return dpu_results } func (this *Ts) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.slice_per_dpu * int64(dpu_id) end_elem := this.slice_per_dpu*int64(dpu_id+1) + this.query_length for _, element := range this.query_buffer { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } for _, element := range this.t_series_buffer[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } for _, element := range this.amean_buffer[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } for _, element := range this.asigma_buffer[start_elem:end_elem] { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Ts) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() return 0, byte_stream } func (this *Ts) NumExecutions() int { return this.num_executions } func (this *Ts) DotProduct(a []int64, a_aux []int64, query []int64, result []int64) []int64 { for i := int64(0); i < this.block_size/this.elem_size; i++ { for j := int64(0); j < this.dotpip; j++ { if (j + i) > (this.block_size/this.elem_size)-1 { result[j] += a_aux[(j+i)-this.block_size/this.elem_size] * query[i] } else { result[j] += a[j+i] * query[i] } } } return result } ================================================ FILE: golang/uPIMulator/src/assembler/prim/uni.go ================================================ package prim import ( "errors" "math" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Uni struct { num_dpus int num_tasklets int num_executions int buffer_a []int64 buffer_c [][]int64 input_size_dpu_round int64 pos int64 input_sizes_dpu []int64 kernels []int64 t_counts [][]int64 firsts [][]int64 lasts [][]int64 } func (this *Uni) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(8) regs := int64(128) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = size } else { input_size = size * int64(this.num_dpus) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if input_size_dpu%(int64(this.num_tasklets)*regs) == 0 { this.input_size_dpu_round = input_size_dpu } else { this.input_size_dpu_round = int64(math.Ceil(float64(input_size_dpu)/float64(int64(this.num_tasklets)*regs))) * int64(this.num_tasklets) * regs } this.buffer_a = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_round*int64(this.num_dpus); i++ { var a int64 if i < input_size { if i%2 == 0 { a = i } else { a = i + 1 } } else { a = this.buffer_a[input_size-1] } this.buffer_a = append(this.buffer_a, a) } this.buffer_c = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { this.buffer_c = append(this.buffer_c, make([]int64, 0)) for j := int64(0); j < this.input_size_dpu_round; j++ { this.buffer_c[i] = append(this.buffer_c[i], 0) } } for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_round * int64(i) this.buffer_c[i][0] = this.buffer_a[start_elem] this.pos = 1 for j := int64(1); j < this.input_size_dpu_round; j++ { if this.buffer_a[start_elem+j] != this.buffer_a[start_elem+j-1] { this.buffer_c[i][this.pos] = this.buffer_a[start_elem+j] this.pos++ } } } this.input_sizes_dpu = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.input_sizes_dpu = append(this.input_sizes_dpu, this.input_size_dpu_round*elem_size) } this.kernels = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.kernels = append(this.kernels, 0) } this.t_counts = make([][]int64, 0) this.firsts = make([][]int64, 0) this.lasts = make([][]int64, 0) for i := 0; i < this.num_dpus; i++ { start_elem := this.input_size_dpu_round * int64(i) this.t_counts = append(this.t_counts, make([]int64, 0)) this.firsts = append(this.firsts, make([]int64, 0)) this.lasts = append(this.lasts, make([]int64, 0)) for j := 0; j < this.num_tasklets; j++ { var t_count int64 var first int64 var last int64 if j == 0 && j != this.num_tasklets-1 { t_count = 0 first = this.buffer_a[start_elem] last = 0 } else if j == this.num_tasklets-1 { t_count = this.pos first = 0 last = this.buffer_c[i][this.pos-1] } else { t_count = 0 first = 0 last = 0 } this.t_counts[i] = append(this.t_counts[i], t_count) this.firsts[i] = append(this.firsts[i], first) this.lasts[i] = append(this.lasts[i], last) } } } func (this *Uni) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() input_size_dpu_word := new(word.Word) input_size_dpu_word.Init(32) input_size_dpu_word.SetValue(this.input_sizes_dpu[dpu_id]) dpu_input_arguments_byte_stream.Merge(input_size_dpu_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[dpu_id]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Uni) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_results_byte_stream := new(encoding.ByteStream) dpu_results_byte_stream.Init() if len(this.t_counts[dpu_id]) != len(this.firsts[dpu_id]) { err := errors.New("t counts' length != firsts' length") panic(err) } else if len(this.t_counts[dpu_id]) != len(this.lasts[dpu_id]) { err := errors.New("t counts' length != lasts' length") panic(err) } for i := 0; i < len(this.t_counts[dpu_id]); i++ { t_count := this.t_counts[dpu_id][i] first := this.firsts[dpu_id][i] last := this.lasts[dpu_id][i] t_count_word := new(word.Word) t_count_word.Init(64) t_count_word.SetValue(t_count) dpu_results_byte_stream.Merge(t_count_word.ToByteStream()) first_word := new(word.Word) first_word.Init(64) first_word.SetValue(first) dpu_results_byte_stream.Merge(first_word.ToByteStream()) last_word := new(word.Word) last_word.Init(64) last_word.SetValue(last) dpu_results_byte_stream.Merge(last_word.ToByteStream()) } dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_RESULTS"] = dpu_results_byte_stream return dpu_host } func (this *Uni) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_round * int64(dpu_id) for i := int64(0); i < this.input_size_dpu_round; i++ { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(this.buffer_a[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Uni) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, element := range this.buffer_c[dpu_id] { element_word := new(word.Word) element_word.Init(64) element_word.SetValue(element) byte_stream.Merge(element_word.ToByteStream()) } return this.input_size_dpu_round * 8, byte_stream } func (this *Uni) NumExecutions() int { return this.num_executions } ================================================ FILE: golang/uPIMulator/src/assembler/prim/va.go ================================================ package prim import ( "errors" "math" "math/rand" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Va struct { num_dpus int num_tasklets int num_executions int input_size_dpu_8bytes int64 buffer_a []int64 buffer_b []int64 buffer_c []int64 sizes []int64 transfer_sizes []int64 kernels []int64 } func (this *Va) Init(command_line_parser *misc.CommandLineParser) { num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.num_executions = 1 buffer_size := int64(command_line_parser.DataPrepParams()[0]) elem_size := int64(4) is_strong_scaling := true var input_size int64 if is_strong_scaling { input_size = buffer_size } else { input_size = buffer_size * int64(this.num_dpus) } var input_size_8bytes int64 if (input_size*elem_size)%8 == 0 { input_size_8bytes = input_size } else { input_size_8bytes = int64(math.Ceil(float64(input_size)/float64(8)) * 8) } input_size_dpu := (input_size-1)/int64(this.num_dpus) + 1 if (input_size_dpu*elem_size)%8 == 0 { this.input_size_dpu_8bytes = input_size_dpu } else { this.input_size_dpu_8bytes = int64(math.Ceil(float64(input_size_dpu)/float64(8)) * 8) } this.buffer_a = make([]int64, 0) this.buffer_b = make([]int64, 0) this.buffer_c = make([]int64, 0) for i := int64(0); i < this.input_size_dpu_8bytes*int64(this.num_dpus); i++ { a := int64(rand.Intn(this.Pow2(31))) b := int64(rand.Intn(this.Pow2(31))) c := a + b this.buffer_a = append(this.buffer_a, a) this.buffer_b = append(this.buffer_b, b) this.buffer_c = append(this.buffer_c, c) } this.sizes = make([]int64, 0) for i := 0; i < this.num_dpus-1; i++ { this.sizes = append(this.sizes, this.input_size_dpu_8bytes*elem_size) } size := (input_size_8bytes - this.input_size_dpu_8bytes*int64(this.num_dpus-1)) * elem_size this.sizes = append(this.sizes, size) this.transfer_sizes = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.transfer_sizes = append(this.transfer_sizes, this.input_size_dpu_8bytes*elem_size) } this.kernels = make([]int64, 0) for i := 0; i < this.num_dpus; i++ { this.kernels = append(this.kernels, 0) } } func (this *Va) InputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } dpu_input_arguments_byte_stream := new(encoding.ByteStream) dpu_input_arguments_byte_stream.Init() size_word := new(word.Word) size_word.Init(32) size_word.SetValue(this.sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(size_word.ToByteStream()) transfer_size_word := new(word.Word) transfer_size_word.Init(32) transfer_size_word.SetValue(this.transfer_sizes[dpu_id]) dpu_input_arguments_byte_stream.Merge(transfer_size_word.ToByteStream()) kernel_word := new(word.Word) kernel_word.Init(32) kernel_word.SetValue(this.kernels[dpu_id]) dpu_input_arguments_byte_stream.Merge(kernel_word.ToByteStream()) dpu_host := make(map[string]*encoding.ByteStream, 0) dpu_host["DPU_INPUT_ARGUMENTS"] = dpu_input_arguments_byte_stream return dpu_host } func (this *Va) OutputDpuHost(execution int, dpu_id int) map[string]*encoding.ByteStream { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } return make(map[string]*encoding.ByteStream, 0) } func (this *Va) InputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_8bytes * int64(dpu_id) for i := int64(0); i < this.input_size_dpu_8bytes; i++ { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(this.buffer_a[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } for i := int64(0); i < this.input_size_dpu_8bytes; i++ { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(this.buffer_b[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } return 0, byte_stream } func (this *Va) OutputDpuMramHeapPointerName( execution int, dpu_id int, ) (int64, *encoding.ByteStream) { if execution >= this.num_executions { err := errors.New("execution >= num executions") panic(err) } else if dpu_id >= this.num_dpus { err := errors.New("DPU ID >= num DPUs") panic(err) } byte_stream := new(encoding.ByteStream) byte_stream.Init() start_elem := this.input_size_dpu_8bytes * int64(dpu_id) for i := int64(0); i < this.input_size_dpu_8bytes; i++ { element_word := new(word.Word) element_word.Init(32) element_word.SetValue(this.buffer_c[start_elem+i]) byte_stream.Merge(element_word.ToByteStream()) } return this.input_size_dpu_8bytes * 4, byte_stream } func (this *Va) NumExecutions() int { return this.num_executions } func (this *Va) Pow2(exponent int) int { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := 1 for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/compiler/compiler.go ================================================ package compiler import ( "os/exec" "path/filepath" "strconv" "uPIMulator/src/misc" ) type Compiler struct { command_line_parser *misc.CommandLineParser root_dirpath string benchmark string num_dpus int num_tasklets int } func (this *Compiler) Init(command_line_parser *misc.CommandLineParser) { this.command_line_parser = command_line_parser this.root_dirpath = command_line_parser.StringParameter("root_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.Build() } func (this *Compiler) Build() { docker_dirpath := filepath.Join(this.root_dirpath, "docker") command := exec.Command("docker", "build", "-t", "bongjoonhyun/upimulator", docker_dirpath) err := command.Run() if err != nil { panic(err) } } func (this *Compiler) Compile() { this.CompileBenchmark() this.CompileSdk() } func (this *Compiler) CompileBenchmark() { command := exec.Command( "docker", "run", "--privileged", "--rm", "-v", this.root_dirpath+":/root/uPIMulator", "bongjoonhyun/upimulator", "python3", "/root/uPIMulator/benchmark/build.py", "--num_dpus", strconv.Itoa(this.num_dpus), "--num_tasklets", strconv.Itoa(this.num_tasklets), ) err := command.Run() if err != nil { panic(err) } } func (this *Compiler) CompileSdk() { command := exec.Command( "docker", "run", "--privileged", "--rm", "-v", this.root_dirpath+":/root/uPIMulator", "bongjoonhyun/upimulator", "python3", "/root/uPIMulator/sdk/build.py", "--num_tasklets", strconv.Itoa(this.num_tasklets), ) err := command.Run() if err != nil { panic(err) } } ================================================ FILE: golang/uPIMulator/src/core/job.go ================================================ package core type Job interface { Execute() } ================================================ FILE: golang/uPIMulator/src/core/thread_pool.go ================================================ package core import ( "errors" "sync" ) type ThreadPool struct { num_threads int channel_size int jobs []Job wg sync.WaitGroup } func (this *ThreadPool) Init(num_threads int) { if num_threads <= 0 { err := errors.New("num threads <= 0") panic(err) } this.num_threads = num_threads this.jobs = make([]Job, 0) } func (this *ThreadPool) Enque(job Job) { this.wg.Add(1) this.jobs = append(this.jobs, job) } func (this *ThreadPool) Start() { for _, job := range this.jobs { go this.Dispatch(job) } this.wg.Wait() } func (this *ThreadPool) Dispatch(job Job) { defer this.wg.Done() job.Execute() } ================================================ FILE: golang/uPIMulator/src/linker/analyze_liveness_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/logic" ) type AnalyzeLivenessJob struct { relocatable *kernel.Relocatable } func (this *AnalyzeLivenessJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *AnalyzeLivenessJob) Execute() { fmt.Printf("Analyzing the liveness of %s...\n", this.relocatable.Path()) liveness_analyzer := new(logic.LivenessAnalyzer) liveness_analyzer.Init() liveness := liveness_analyzer.Analyze(this.relocatable) this.relocatable.SetLiveness(liveness) } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/ascii_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" ) type AsciiDirective struct { characters string } func (this *AsciiDirective) Init(characters string) { this.characters = characters } func (this *AsciiDirective) Characters() string { return this.characters } func (this *AsciiDirective) Size() int64 { return int64(len(this.characters)) } func (this *AsciiDirective) Encode() *encoding.ByteStream { ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() return ascii_encoder.Encode(this.characters) } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/asciz_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" ) type AscizDirective struct { characters string } func (this *AscizDirective) Init(characters string) { this.characters = characters } func (this *AscizDirective) Characters() string { return this.characters } func (this *AscizDirective) Size() int64 { return int64(len(this.characters)) + 1 } func (this *AscizDirective) Encode() *encoding.ByteStream { ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() return ascii_encoder.Encode(this.characters + ascii_encoder.Unknown()) } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/byte_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" ) type ByteDirective struct { immediate *word.Immediate } func (this *ByteDirective) Init(value int64) { this.immediate = new(word.Immediate) this.immediate.Init(word.UNSIGNED, 8*int(this.Size()), value) } func (this *ByteDirective) Size() int64 { return 1 } func (this *ByteDirective) Immediate() *word.Immediate { return this.immediate } func (this *ByteDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/long_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" ) type LongDirective struct { immediate *word.Immediate } func (this *LongDirective) Init(value int64) { this.immediate = new(word.Immediate) this.immediate.Init(word.UNSIGNED, 8*int(this.Size()), value) } func (this *LongDirective) Size() int64 { return 4 } func (this *LongDirective) Immediate() *word.Immediate { return this.immediate } func (this *LongDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/quad_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" ) type QuadDirective struct { immediate *word.Immediate } func (this *QuadDirective) Init(value int64) { this.immediate = new(word.Immediate) this.immediate.Init(word.UNSIGNED, 8*int(this.Size()), value) } func (this *QuadDirective) Size() int64 { return 8 } func (this *QuadDirective) Immediate() *word.Immediate { return this.immediate } func (this *QuadDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/short_directive.go ================================================ package directive import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" ) type ShortDirective struct { immediate *word.Immediate } func (this *ShortDirective) Init(value int64) { this.immediate = new(word.Immediate) this.immediate.Init(word.UNSIGNED, 8*int(this.Size()), value) } func (this *ShortDirective) Size() int64 { return 2 } func (this *ShortDirective) Immediate() *word.Immediate { return this.immediate } func (this *ShortDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang/uPIMulator/src/linker/kernel/directive/zero_directive.go ================================================ package directive import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" ) type ZeroDirective struct { size int64 immediate *word.Immediate } func (this *ZeroDirective) Init(size int64, value int64) { if size <= 0 { err := errors.New("size <= 0") panic(err) } this.size = size this.immediate = new(word.Immediate) this.immediate.Init(word.UNSIGNED, 8, value) } func (this *ZeroDirective) Size() int64 { return this.size } func (this *ZeroDirective) Immediate() *word.Immediate { return this.immediate } func (this *ZeroDirective) Encode() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < this.size; i++ { byte_stream.Merge(this.immediate.ToByteStream()) } return byte_stream } ================================================ FILE: golang/uPIMulator/src/linker/kernel/encodable.go ================================================ package kernel import ( "uPIMulator/src/abi/encoding" ) type Encodable interface { Encode() *encoding.ByteStream } ================================================ FILE: golang/uPIMulator/src/linker/kernel/executable.go ================================================ package kernel import ( "errors" "fmt" "sort" "uPIMulator/src/abi/encoding" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/misc" ) type Executable struct { name string path string benchmark_relocatable *Relocatable sdk_relocatables map[*Relocatable]bool token_stream *lexer.TokenStream ast *parser.Ast liveness *Liveness sections map[*Section]bool cur_section *Section } func (this *Executable) Init(name string) { this.name = name this.sdk_relocatables = make(map[*Relocatable]bool, 0) this.liveness = new(Liveness) this.liveness.Init() this.sections = make(map[*Section]bool, 0) } func (this *Executable) Name() string { return this.name } func (this *Executable) Path() string { return this.path } func (this *Executable) SetPath(path string) { this.path = path } func (this *Executable) SetBenchmarkRelocatable(relocatable *Relocatable) { this.benchmark_relocatable = relocatable this.UpdateUnresolvedSymbols(relocatable) } func (this *Executable) AddSdkRelocatable(relocatable *Relocatable) { this.sdk_relocatables[relocatable] = true this.UpdateLocalSymbols(relocatable) this.UpdateUnresolvedSymbols(relocatable) } func (this *Executable) TokenStream() *lexer.TokenStream { return this.token_stream } func (this *Executable) SetTokenStream(token_stream *lexer.TokenStream) { this.token_stream = token_stream } func (this *Executable) Ast() *parser.Ast { return this.ast } func (this *Executable) SetAst(ast *parser.Ast) { this.ast = ast } func (this *Executable) Liveness() *Liveness { return this.liveness } func (this *Executable) DumpAssembly() { lines := this.benchmark_relocatable.Lines() for sdk_relocatable, _ := range this.sdk_relocatables { lines = append(lines, sdk_relocatable.Lines()...) } file_dumper := new(misc.FileDumper) file_dumper.Init(this.path) file_dumper.WriteLines(lines) } func (this *Executable) DumpAddresses(path string) { lines := make([]string, 0) for label_name, label_address := range this.Addresses() { line := fmt.Sprintf("%s: %d", label_name, label_address) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpAtomic(path string) { atomic_byte_stream := this.AtomicByteStream() lines := make([]string, 0) for i := int64(0); i < atomic_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", atomic_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpIram(path string) { iram_byte_stream := this.IramByteStream() lines := make([]string, 0) for i := int64(0); i < iram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", iram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpWram(path string) { wram_byte_stream := this.WramByteStream() lines := make([]string, 0) for i := int64(0); i < wram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", wram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpMram(path string) { mram_byte_stream := this.MramByteStream() lines := make([]string, 0) for i := int64(0); i < mram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", mram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) Section(section_name SectionName, name string) *Section { for section, _ := range this.sections { if section.SectionName() == section_name && section.Name() == name { return section } } return nil } func (this *Executable) Sections(section_name SectionName) map[*Section]bool { sections := make(map[*Section]bool, 0) for section, _ := range this.sections { if section.SectionName() == section_name { sections[section] = true } } return sections } func (this *Executable) AddSection( section_name SectionName, name string, section_flags map[SectionFlag]bool, section_type SectionType, ) { if this.Section(section_name, name) == nil { section := new(Section) section.Init(section_name, name, section_flags, section_type) this.sections[section] = true } } func (this *Executable) CurSection() *Section { return this.cur_section } func (this *Executable) CheckoutSection(section_name SectionName, name string) { if section := this.Section(section_name, name); section != nil { this.cur_section = section } else { err := errors.New("section is not found") panic(err) } } func (this *Executable) Label(label_name string) *Label { var label *Label = nil for section, _ := range this.sections { section_label := section.Label(label_name) if section_label != nil { if label != nil { err := errors.New("labels are duplicated") panic(err) } label = section_label } } return label } func (this *Executable) Addresses() map[string]int64 { addresses := make(map[string]int64, 0) for section, _ := range this.sections { for _, label := range section.Labels() { addresses[label.Name()] = label.Address() } } return addresses } func (this *Executable) AtomicByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() atomic_sections := this.Sort( config_loader.AtomicOffset(), config_loader.AtomicOffset()+config_loader.AtomicSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, atomic_section := range atomic_sections { byte_stream.Merge(atomic_section.ToByteStream()) } return byte_stream } func (this *Executable) IramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_sections := this.Sort( config_loader.IramOffset(), config_loader.IramOffset()+config_loader.IramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, iram_section := range iram_sections { byte_stream.Merge(iram_section.ToByteStream()) } return byte_stream } func (this *Executable) WramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() wram_sections := this.Sort( config_loader.WramOffset(), config_loader.WramOffset()+config_loader.WramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, wram_section := range wram_sections { byte_stream.Merge(wram_section.ToByteStream()) } return byte_stream } func (this *Executable) MramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_sections := this.Sort( config_loader.MramOffset(), config_loader.MramOffset()+config_loader.MramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, mram_section := range mram_sections { byte_stream.Merge(mram_section.ToByteStream()) } return byte_stream } func (this *Executable) UpdateLocalSymbols(relocatable *Relocatable) { for old_name, _ := range relocatable.Liveness().LocalSymbols() { new_name := relocatable.Name() + "." + old_name relocatable.RenameLocalSymbol(old_name, new_name) } } func (this *Executable) UpdateUnresolvedSymbols(relocatable *Relocatable) { for def, _ := range relocatable.Liveness().Defs() { this.liveness.AddDef(def) } for use, _ := range relocatable.Liveness().Uses() { this.liveness.AddUse(use) } for global_symbol, _ := range relocatable.Liveness().GlobalSymbols() { this.liveness.AddGlobalSymbol(global_symbol) } } func (this *Executable) Sort(begin_address int64, end_address int64) []*Section { sections := make([]*Section, 0) for section, _ := range this.sections { address := section.Address() if begin_address <= address && address < end_address { sections = append(sections, section) } } sort_fn := func(i int, j int) bool { return sections[i].Address() < sections[j].Address() } sort.Slice(sections, sort_fn) return sections } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/acquire_cc.go ================================================ package cc import ( "errors" ) type AcquireCc struct { condition Condition } func (this *AcquireCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *AcquireCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/add_nz_cc.go ================================================ package cc import ( "errors" ) type AddNzCc struct { condition Condition } func (this *AddNzCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, NC5: true, NC6: true, NC7: true, NC8: true, NC9: true, NC10: true, NC11: true, NC12: true, NC13: true, NC14: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *AddNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/boot_cc.go ================================================ package cc import ( "errors" ) type BootCc struct { condition Condition } func (this *BootCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *BootCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/cc.go ================================================ package cc type Condition int const ( TRUE Condition = iota FALSE Z NZ E O PL MI OV NOV C NC SZ SNZ SPL SMI SO SE NC5 NC6 NC7 NC8 NC9 NC10 NC11 NC12 NC13 NC14 MAX NMAX SH32 NSH32 EQ NEQ LTU LEU GTU GEU LTS LES GTS GES XZ XNZ XLEU XGTU XLES XGTS SMALL LARGE ) type Cc interface { Condition() Condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/const_cc_ge0.go ================================================ package cc import ( "errors" ) type ConstCcGe0 struct { condition Condition } func (this *ConstCcGe0) Init(condition Condition) { conditions := map[Condition]bool{ PL: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcGe0) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/const_cc_geu.go ================================================ package cc import ( "errors" ) type ConstCcGeu struct { condition Condition } func (this *ConstCcGeu) Init(condition Condition) { conditions := map[Condition]bool{ GEU: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcGeu) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/const_cc_zero.go ================================================ package cc import ( "errors" ) type ConstCcZero struct { condition Condition } func (this *ConstCcZero) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcZero) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/count_nz_cc.go ================================================ package cc import ( "errors" ) type CountNzCc struct { condition Condition } func (this *CountNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, MAX: true, NMAX: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *CountNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/div_cc.go ================================================ package cc import ( "errors" ) type DivCc struct { condition Condition } func (this *DivCc) Init(condition Condition) { conditions := map[Condition]bool{ SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *DivCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/div_nz_cc.go ================================================ package cc import ( "errors" ) type DivNzCc struct { condition Condition } func (this *DivNzCc) Init(condition Condition) { conditions := map[Condition]bool{ SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *DivNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/ext_sub_set_cc.go ================================================ package cc import ( "errors" ) type ExtSubSetCc struct { condition Condition } func (this *ExtSubSetCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, EQ: true, NEQ: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, GES: true, GEU: true, GTS: true, GTU: true, LES: true, LEU: true, LTS: true, LTU: true, XGTS: true, XGTU: true, XLES: true, XLEU: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ExtSubSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/false_cc.go ================================================ package cc import ( "errors" ) type FalseCc struct { condition Condition } func (this *FalseCc) Init(condition Condition) { conditions := map[Condition]bool{ FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *FalseCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/imm_shift_nz_cc.go ================================================ package cc import ( "errors" ) type ImmShiftNzCc struct { condition Condition } func (this *ImmShiftNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, E: true, O: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, SE: true, SO: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ImmShiftNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/log_nz_cc.go ================================================ package cc import ( "errors" ) type LogNzCc struct { condition Condition } func (this *LogNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *LogNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/log_set_cc.go ================================================ package cc import ( "errors" ) type LogSetCc struct { condition Condition } func (this *LogSetCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *LogSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/mul_nz_cc.go ================================================ package cc import ( "errors" ) type MulNzCc struct { condition Condition } func (this *MulNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, LARGE: true, SMALL: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *MulNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/no_cc.go ================================================ package cc import ( "errors" ) type NoCc struct { condition Condition } func (this *NoCc) Init(condition Condition) { conditions := map[Condition]bool{} if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *NoCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/release_cc.go ================================================ package cc import ( "errors" ) type ReleaseCc struct { condition Condition } func (this *ReleaseCc) Init(condition Condition) { conditions := map[Condition]bool{ NZ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ReleaseCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/shift_nz_cc.go ================================================ package cc import ( "errors" ) type ShiftNzCc struct { condition Condition } func (this *ShiftNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, E: true, O: true, PL: true, MI: true, SZ: true, SNZ: true, SE: true, SO: true, SPL: true, SMI: true, SH32: true, NSH32: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ShiftNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/sub_nz_cc.go ================================================ package cc import ( "errors" ) type SubNzCc struct { condition Condition } func (this *SubNzCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, MI: true, PL: true, EQ: true, NEQ: true, SPL: true, SMI: true, GES: true, GEU: true, GTS: true, GTU: true, LES: true, LEU: true, LTS: true, LTU: true, XGTS: true, XGTU: true, XLES: true, XLEU: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *SubNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/sub_set_cc.go ================================================ package cc import ( "errors" ) type SubSetCc struct { condition Condition } func (this *SubSetCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, EQ: true, NEQ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *SubSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/true_cc.go ================================================ package cc import ( "errors" ) type TrueCc struct { condition Condition } func (this *TrueCc) Init(condition Condition) { conditions := map[Condition]bool{ TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *TrueCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/cc/true_false_cc.go ================================================ package cc import ( "errors" ) type TrueFalseCc struct { condition Condition } func (this *TrueFalseCc) Init(condition Condition) { conditions := map[Condition]bool{ TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *TrueFalseCc) Condition() Condition { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/endian.go ================================================ package instruction type Endian int const ( LITTLE Endian = iota BIG ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/exception.go ================================================ package instruction type Exception int const ( MEMORY_FAULT Exception = iota DMA_FAULT HEAP_FULL DIVISION_BY_ZERO ASSERT HALT PRINT_OVERFLOW ALREADY_PROFILING NOT_PROFILING ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/flag.go ================================================ package instruction type Flag int const ( ZERO Flag = iota CARRY ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/instruction.go ================================================ package instruction import ( "errors" "math" "strconv" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/linker/kernel/instruction/cc" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type Instruction struct { op_code OpCode suffix Suffix rc *reg_descriptor.GpRegDescriptor ra *reg_descriptor.SrcRegDescriptor rb *reg_descriptor.SrcRegDescriptor dc *reg_descriptor.PairRegDescriptor db *reg_descriptor.PairRegDescriptor condition *cc.Condition imm *word.Immediate off *word.Immediate pc *word.Immediate endian *Endian } func (this *Instruction) InitRici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RiciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } this.op_code = op_code this.suffix = RICI this.ra = ra this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 16, imm) this.condition = new(cc.Condition) *this.condition = condition config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRri( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } this.op_code = op_code this.suffix = RRI this.rc = rc this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) InitRric( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } this.op_code = op_code this.suffix = RRIC this.rc = rc this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) ext_sub_setcc := new(cc.ExtSubSetCc) ext_sub_setcc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_setcc.Condition() } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } } func (this *Instruction) InitRrici( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } this.op_code = op_code this.suffix = RRICI this.rc = rc this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRrif( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } this.op_code = op_code this.suffix = RRIF this.rc = rc this.ra = ra this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) false_cc := new(cc.FalseCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitRrr( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } this.op_code = op_code this.suffix = RRR this.rc = rc this.ra = ra this.rb = rb } func (this *Instruction) InitRrrc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } this.op_code = op_code this.suffix = RRRC this.rc = rc this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitRrrci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } this.op_code = op_code this.suffix = RRRCI this.rc = rc this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZri(op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } this.op_code = op_code this.suffix = ZRI this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 28, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) InitZric( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } this.op_code = op_code this.suffix = ZRIC this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) ext_sub_setcc := new(cc.ExtSubSetCc) ext_sub_setcc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_setcc.Condition() } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } } func (this *Instruction) InitZrici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } this.op_code = op_code this.suffix = ZRICI this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZrif( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } this.op_code = op_code this.suffix = ZRIF this.ra = ra this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) false_cc := new(cc.LogSetCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitZrr( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } this.op_code = op_code this.suffix = ZRR this.ra = ra this.rb = rb } func (this *Instruction) InitZrrc( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } this.op_code = op_code this.suffix = ZRRC this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitZrrci( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } this.op_code = op_code this.suffix = ZRRCI this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRri( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if suffix != S_RRI && suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid S_RRI nor U_RRI op code") panic(err) } } func (this *Instruction) InitSRric( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if suffix != S_RRIC && suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid S_RRI nor U_RRI op code") panic(err) } } func (this *Instruction) InitSRrici( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if suffix != S_RRICI && suffix != U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRrif( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if suffix != S_RRIF && suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) false_cc := new(cc.FalseCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitSRrr( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if suffix != S_RRR && suffix != U_RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb } func (this *Instruction) InitSRrrc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if suffix != S_RRRC && suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitSRrrci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if suffix != S_RRRCI && suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRr( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } this.op_code = op_code this.suffix = RR this.rc = rc this.ra = ra } func (this *Instruction) InitRrc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } this.op_code = op_code this.suffix = RRC this.rc = rc this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitRrci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } this.op_code = op_code this.suffix = RRCI this.rc = rc this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZr(op_code OpCode, ra *reg_descriptor.SrcRegDescriptor) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } this.op_code = op_code this.suffix = ZR this.ra = ra } func (this *Instruction) InitZrc( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } this.op_code = op_code this.suffix = ZRC this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitZrci( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } this.op_code = op_code this.suffix = ZRCI this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRr( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if suffix != S_RR && suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra } func (this *Instruction) InitSRrc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if suffix != S_RRC && suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitSRrci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if suffix != S_RRCI && suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitDrdici( op_code OpCode, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, db *reg_descriptor.PairRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.DrdiciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } this.op_code = op_code this.suffix = DRDICI this.dc = dc this.ra = ra this.db = db this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) if _, is_div_step_drdici_op_code := this.DivStepDrdiciOpCodes()[op_code]; is_div_step_drdici_op_code { div_cc := new(cc.DivCc) div_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_cc.Condition() } else if _, is_mul_step_drdici_op_code := this.MulStepDrdiciOpCodes()[op_code]; is_mul_step_drdici_op_code { boot_cc := new(cc.BootCc) boot_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = boot_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRrri( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } this.op_code = op_code this.suffix = RRRI this.rc = rc this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) InitRrrici( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } this.op_code = op_code this.suffix = RRRICI this.rc = rc this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZrri( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } this.op_code = op_code this.suffix = ZRRI this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) InitZrrici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } this.op_code = op_code this.suffix = ZRRICI this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRrri( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if suffix != S_RRRI && suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) InitSRrrici( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if suffix != S_RRRICI && suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRir( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } this.op_code = op_code this.suffix = RIR this.rc = rc this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) this.ra = ra } func (this *Instruction) InitRirc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } this.op_code = op_code this.suffix = RIRC this.rc = rc this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitRirci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } this.op_code = op_code this.suffix = RIRCI this.rc = rc this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZir(op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor) { if _, found := this.RirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } this.op_code = op_code this.suffix = ZIR this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) this.ra = ra } func (this *Instruction) InitZirc( op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } this.op_code = op_code this.suffix = ZIRC this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitZirci( op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } this.op_code = op_code this.suffix = ZIRCI this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRirc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if suffix != S_RIRC && suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitSRirci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if suffix != S_RIRCI && suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitR(op_code OpCode, rc *reg_descriptor.GpRegDescriptor) { if _, found := this.ROpCodes()[op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } this.op_code = op_code this.suffix = R this.rc = rc } func (this *Instruction) InitRci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } this.op_code = op_code this.suffix = RCI this.rc = rc true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZ(op_code OpCode) { if _, found := this.ROpCodes()[op_code]; !found && op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } this.op_code = op_code this.suffix = Z } func (this *Instruction) InitZci( op_code OpCode, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } this.op_code = op_code this.suffix = ZCI true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSR( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ) { if _, found := this.ROpCodes()[op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if suffix != S_R && suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc } func (this *Instruction) InitSRci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if suffix != S_RCI && suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitCi(op_code OpCode, condition cc.Condition, pc int64) { if _, found := this.CiOpCodes()[op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } this.op_code = op_code this.suffix = CI boot_cc := new(cc.BootCc) boot_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = boot_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitI(op_code OpCode, imm int64) { if _, found := this.IOpCodes()[op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } this.op_code = op_code this.suffix = I this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } func (this *Instruction) InitDdci( op_code OpCode, dc *reg_descriptor.PairRegDescriptor, db *reg_descriptor.PairRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.DdciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } this.op_code = op_code this.suffix = DDCI this.dc = dc this.db = db true_false_cc := new(cc.TrueFalseCc) true_false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_false_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitErri( op_code OpCode, endian Endian, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.ErriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } this.op_code = op_code this.suffix = ERRI this.endian = new(Endian) *this.endian = endian this.rc = rc this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) InitSErri( op_code OpCode, suffix Suffix, endian Endian, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.ErriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if suffix != S_ERRI && suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } this.op_code = op_code this.suffix = suffix this.endian = new(Endian) *this.endian = endian this.dc = dc this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) InitEdri( op_code OpCode, endian Endian, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.EdriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } this.op_code = op_code this.suffix = EDRI this.endian = new(Endian) *this.endian = endian this.dc = dc this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) InitErii( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, imm int64, ) { if _, found := this.EriiOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } this.op_code = op_code this.suffix = ERII this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 16, imm) } func (this *Instruction) InitErir( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.ErirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } this.op_code = op_code this.suffix = ERIR this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) this.rb = rb } func (this *Instruction) InitErid( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, db *reg_descriptor.PairRegDescriptor, ) { if _, found := this.EridOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } this.op_code = op_code this.suffix = ERID this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) this.db = db } func (this *Instruction) InitDmaRri( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.DmaRriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DMA RRI op code") panic(err) } this.op_code = op_code this.suffix = DMA_RRI this.ra = ra this.rb = rb this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 8, imm) } func (this *Instruction) OpCode() OpCode { return this.op_code } func (this *Instruction) Suffix() Suffix { return this.suffix } func (this *Instruction) Rc() *reg_descriptor.GpRegDescriptor { return this.rc } func (this *Instruction) Ra() *reg_descriptor.SrcRegDescriptor { return this.ra } func (this *Instruction) Rb() *reg_descriptor.SrcRegDescriptor { return this.rb } func (this *Instruction) Dc() *reg_descriptor.PairRegDescriptor { return this.dc } func (this *Instruction) Db() *reg_descriptor.PairRegDescriptor { return this.db } func (this *Instruction) Condition() cc.Condition { if this.condition == nil { err := errors.New("condition == nil") panic(err) } return *this.condition } func (this *Instruction) Imm() *word.Immediate { return this.imm } func (this *Instruction) Off() *word.Immediate { return this.off } func (this *Instruction) Pc() *word.Immediate { return this.pc } func (this *Instruction) Endian() Endian { if this.endian == nil { err := errors.New("endian == nil") panic(err) } return *this.endian } func (this *Instruction) Encode() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() word_ := new(word.Word) word_.Init(config_loader.IramDataWidth()) this.EncodeOpCode(word_) this.EncodeSuffix(word_) if this.suffix == RICI { this.EncodeRici(word_) } else if this.suffix == RRI { this.EncodeRri(word_) } else if this.suffix == RRIC { this.EncodeRric(word_) } else if this.suffix == RRICI { this.EncodeRrici(word_) } else if this.suffix == RRIF { this.EncodeRrif(word_) } else if this.suffix == RRR { this.EncodeRrr(word_) } else if this.suffix == RRRC { this.EncodeRrrc(word_) } else if this.suffix == RRRCI { this.EncodeRrrci(word_) } else if this.suffix == ZRI { this.EncodeZri(word_) } else if this.suffix == ZRIC { this.EncodeZric(word_) } else if this.suffix == ZRICI { this.EncodeZrici(word_) } else if this.suffix == ZRIF { this.EncodeZrif(word_) } else if this.suffix == ZRR { this.EncodeZrr(word_) } else if this.suffix == ZRRC { this.EncodeZrrc(word_) } else if this.suffix == ZRRCI { this.EncodeZrrci(word_) } else if this.suffix == S_RRI || this.suffix == U_RRI { this.EncodeSRri(word_) } else if this.suffix == S_RRIC || this.suffix == U_RRIC { this.EncodeSRric(word_) } else if this.suffix == S_RRICI || this.suffix == U_RRICI { this.EncodeSRrici(word_) } else if this.suffix == S_RRIF || this.suffix == U_RRIF { this.EncodeSRrif(word_) } else if this.suffix == S_RRR || this.suffix == U_RRR { this.EncodeSRrr(word_) } else if this.suffix == S_RRRC || this.suffix == U_RRRC { this.EncodeSRrrc(word_) } else if this.suffix == S_RRRCI || this.suffix == U_RRRCI { this.EncodeSRrrci(word_) } else if this.suffix == RR { this.EncodeRr(word_) } else if this.suffix == RRC { this.EncodeRrc(word_) } else if this.suffix == RRCI { this.EncodeRrci(word_) } else if this.suffix == ZR { this.EncodeZr(word_) } else if this.suffix == ZRC { this.EncodeZrc(word_) } else if this.suffix == ZRCI { this.EncodeZrci(word_) } else if this.suffix == S_RR || this.suffix == U_RR { this.EncodeSRr(word_) } else if this.suffix == S_RRC || this.suffix == U_RRC { this.EncodeSRrc(word_) } else if this.suffix == S_RRCI || this.suffix == U_RRCI { this.EncodeSRrci(word_) } else if this.suffix == DRDICI { this.EncodeDrdici(word_) } else if this.suffix == RRRI { this.EncodeRrri(word_) } else if this.suffix == RRRICI { this.EncodeRrrici(word_) } else if this.suffix == ZRRI { this.EncodeZrri(word_) } else if this.suffix == ZRRICI { this.EncodeZrrici(word_) } else if this.suffix == S_RRRI || this.suffix == U_RRRI { this.EncodeSRrri(word_) } else if this.suffix == S_RRRICI || this.suffix == U_RRRICI { this.EncodeSRrrici(word_) } else if this.suffix == RIR { this.EncodeRir(word_) } else if this.suffix == RIRC { this.EncodeRirc(word_) } else if this.suffix == RIRCI { this.EncodeRirci(word_) } else if this.suffix == ZIR { this.EncodeZir(word_) } else if this.suffix == ZIRC { this.EncodeZirc(word_) } else if this.suffix == ZIRCI { this.EncodeZirci(word_) } else if this.suffix == S_RIRC || this.suffix == U_RIRC { this.EncodeSRirc(word_) } else if this.suffix == S_RIRCI || this.suffix == U_RIRCI { this.EncodeSRirci(word_) } else if this.suffix == R { this.EncodeR(word_) } else if this.suffix == RCI { this.EncodeRci(word_) } else if this.suffix == Z { this.EncodeZ(word_) } else if this.suffix == ZCI { this.EncodeZci(word_) } else if this.suffix == S_R || this.suffix == U_R { this.EncodeSR(word_) } else if this.suffix == S_RCI || this.suffix == U_RCI { this.EncodeSRci(word_) } else if this.suffix == CI { this.EncodeCi(word_) } else if this.suffix == I { this.EncodeI(word_) } else if this.suffix == DDCI { this.EncodeDdci(word_) } else if this.suffix == ERRI { this.EncodeErri(word_) } else if this.suffix == S_ERRI || this.suffix == U_ERRI { this.EncodeSErri(word_) } else if this.suffix == EDRI { this.EncodeEdri(word_) } else if this.suffix == ERII { this.EncodeErii(word_) } else if this.suffix == ERIR { this.EncodeErir(word_) } else if this.suffix == ERID { this.EncodeErid(word_) } else if this.suffix == DMA_RRI { this.EncodeDmaRri(word_) } else { err := errors.New("op code is not valid") panic(err) } return word_.ToByteStream() } func (this *Instruction) EncodeRici(word_ *word.Word) { if _, found := this.RiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } if this.suffix != RICI { err := errors.New("suffix is not RICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.pc.Width() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != RRI { err := errors.New("suffix is not RRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeRric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != RRIC { err := errors.New("suffix is not RRIC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != RRICI { err := errors.New("suffix is not RRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != RRIF { err := errors.New("suffix is not RRIF") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not RRR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeRrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != RRRC { err := errors.New("suffix is not RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != ZRI { err := errors.New("suffix is not ZRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeZric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != ZRIF { err := errors.New("suffix is not RRIF") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != ZRR { err := errors.New("suffix is not RRR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeZrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != S_RRI && this.suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeSRric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != S_RRIC && this.suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != S_RRICI && this.suffix != U_RRICI { err := errors.New("suffix is not RRICI nor U_RRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != S_RRIF && this.suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeSRrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != S_RRRC && this.suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != S_RRRCI && this.suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != RR { err := errors.New("suffix is not RR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeRrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != RRC { err := errors.New("suffix is not RRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != RRCI { err := errors.New("suffix is not RRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != ZR { err := errors.New("suffix is not ZR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeZrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != ZRC { err := errors.New("suffix is not RRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != S_RR && this.suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeSRrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != S_RRC && this.suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != S_RRCI && this.suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeDrdici(word_ *word.Word) { if _, found := this.DrdiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } if this.suffix != DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) db_begin := ra_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) imm_begin := db_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != RRRI { err := errors.New("suffix is not RRRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeRrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeZrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != S_RRRI && this.suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeSRrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != S_RRRICI && this.suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRir(word_ *word.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != RIR { err := errors.New("suffix is not RIR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeRirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != RIRC { err := errors.New("suffix is not RIRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZir(word_ *word.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != ZIR { err := errors.New("suffix is not ZIR") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeZirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != S_RIRC && this.suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) imm_begin := dc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != S_RIRCI && this.suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) imm_begin := dc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeR(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != R { err := errors.New("suffix is not R") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) } func (this *Instruction) EncodeRci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != RCI { err := errors.New("suffix is not RCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) condition_begin := rc_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZ(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found && this.op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } if this.suffix != Z { err := errors.New("suffix is not Z") panic(err) } } func (this *Instruction) EncodeZci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != ZCI { err := errors.New("suffix is not ZCI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSR(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != S_R && this.suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) } func (this *Instruction) EncodeSRci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != S_RCI && this.suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) condition_begin := dc_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeCi(word_ *word.Word) { if _, found := this.CiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } if this.suffix != CI { err := errors.New("suffix is not CI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeI(word_ *word.Word) { if _, found := this.IOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } if this.suffix != I { err := errors.New("suffix is not I") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeDdci(word_ *word.Word) { if _, found := this.DdciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } if this.suffix != DDCI { err := errors.New("suffix is not DDCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) db_begin := dc_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) condition_begin := db_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeErri(word_ *word.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != ERRI { err := errors.New("suffix is not ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) rc_begin := endian_end rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeSErri(word_ *word.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != S_ERRI && this.suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeEdri(word_ *word.Word) { if _, found := this.EdriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } if this.suffix != EDRI { err := errors.New("suffix is not EDRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeErii(word_ *word.Word) { if _, found := this.EriiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } if this.suffix != ERII { err := errors.New("suffix is not ERII") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) imm_begin := off_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeErir(word_ *word.Word) { if _, found := this.ErirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } if this.suffix != ERIR { err := errors.New("suffix is not ERIR") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) rb_begin := off_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeErid(word_ *word.Word) { if _, found := this.EridOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } if this.suffix != ERID { err := errors.New("suffix is not ERID") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) db_begin := off_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) } func (this *Instruction) EncodeDmaRri(word_ *word.Word) { if _, found := this.DmaRriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } if this.suffix != DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeOpCode(word_ *word.Word) { word_.SetBitSlice(this.OpCodeBegin(), this.OpCodeEnd(), int64(this.op_code)) } func (this *Instruction) EncodeSuffix(word_ *word.Word) { word_.SetBitSlice(this.SuffixBegin(), this.SuffixEnd(), int64(this.suffix)) } func (this *Instruction) EncodeGpRegDescriptor( word_ *word.Word, begin int, end int, gp_reg_descriptor *reg_descriptor.GpRegDescriptor, ) { word_.SetBitSlice(begin, end, int64(gp_reg_descriptor.Index())) } func (this *Instruction) EncodeSrcRegDescriptor( word_ *word.Word, begin int, end int, src_reg_descriptor *reg_descriptor.SrcRegDescriptor, ) { if src_reg_descriptor.IsGpRegDescriptor() { word_.SetBitSlice(begin, end, int64(src_reg_descriptor.GpRegDescriptor().Index())) } else if src_reg_descriptor.IsSpRegDescriptor() { config_loader := new(misc.ConfigLoader) config_loader.Init() index := config_loader.NumGpRegisters() + int(*src_reg_descriptor.SpRegDescriptor()) word_.SetBitSlice(begin, end, int64(index)) } else { err := errors.New("sp reg descriptor is corrupted") panic(err) } } func (this *Instruction) EncodePairRegDescriptor( word_ *word.Word, begin int, end int, pair_reg_descriptor *reg_descriptor.PairRegDescriptor, ) { word_.SetBitSlice(begin, end, int64(pair_reg_descriptor.Index())) } func (this *Instruction) EncodeImm(word_ *word.Word, begin int, end int, value int64) { word_.SetBitSlice(begin, end, value) } func (this *Instruction) EncodeCondition( word_ *word.Word, begin int, end int, condition cc.Condition, ) { word_.SetBitSlice(begin, end, int64(condition)) } func (this *Instruction) EncodePc(word_ *word.Word, begin int, end int, pc int64) { this.EncodeImm(word_, begin, end, pc) } func (this *Instruction) EncodeEndian(word_ *word.Word, begin int, end int, endian Endian) { word_.SetBitSlice(begin, end, int64(endian)) } func (this *Instruction) EncodeOff(word_ *word.Word, begin int, end int, value int64) { this.EncodeImm(word_, begin, end, value) } func (this *Instruction) Decode(byte_stream *encoding.ByteStream) { config_loader := new(misc.ConfigLoader) config_loader.Init() word_ := new(word.Word) word_.Init(config_loader.IramDataWidth()) word_.FromByteStream(byte_stream) this.op_code = this.DecodeOpCode(word_) this.suffix = this.DecodeSuffix(word_) if this.suffix == RICI { this.DecodeRici(word_) } else if this.suffix == RRI { this.DecodeRri(word_) } else if this.suffix == RRIC { this.DecodeRric(word_) } else if this.suffix == RRICI { this.DecodeRrici(word_) } else if this.suffix == RRIF { this.DecodeRrif(word_) } else if this.suffix == RRR { this.DecodeRrr(word_) } else if this.suffix == RRRC { this.DecodeRrrc(word_) } else if this.suffix == RRRCI { this.DecodeRrrci(word_) } else if this.suffix == ZRI { this.DecodeZri(word_) } else if this.suffix == ZRIC { this.DecodeZric(word_) } else if this.suffix == ZRICI { this.DecodeZrici(word_) } else if this.suffix == ZRIF { this.DecodeZrif(word_) } else if this.suffix == ZRR { this.DecodeZrr(word_) } else if this.suffix == ZRRC { this.DecodeZrrc(word_) } else if this.suffix == ZRRCI { this.DecodeZrrci(word_) } else if this.suffix == S_RRI || this.suffix == U_RRI { this.DecodeSRri(word_) } else if this.suffix == S_RRIC || this.suffix == U_RRIC { this.DecodeSRric(word_) } else if this.suffix == S_RRICI || this.suffix == U_RRICI { this.DecodeSRrici(word_) } else if this.suffix == S_RRIF || this.suffix == U_RRIF { this.DecodeSRrif(word_) } else if this.suffix == S_RRR || this.suffix == U_RRR { this.DecodeSRrr(word_) } else if this.suffix == S_RRRC || this.suffix == U_RRRC { this.DecodeSRrrc(word_) } else if this.suffix == S_RRRCI || this.suffix == U_RRRCI { this.DecodeSRrrci(word_) } else if this.suffix == RR { this.DecodeRr(word_) } else if this.suffix == RRC { this.DecodeRrc(word_) } else if this.suffix == RRCI { this.DecodeRrci(word_) } else if this.suffix == ZR { this.DecodeZr(word_) } else if this.suffix == ZRC { this.DecodeZrc(word_) } else if this.suffix == ZRCI { this.DecodeZrci(word_) } else if this.suffix == S_RR || this.suffix == U_RR { this.DecodeSRr(word_) } else if this.suffix == S_RRC || this.suffix == U_RRC { this.DecodeSRrc(word_) } else if this.suffix == S_RRCI || this.suffix == U_RRCI { this.DecodeSRrci(word_) } else if this.suffix == DRDICI { this.DecodeDrdici(word_) } else if this.suffix == RRRI { this.DecodeRrri(word_) } else if this.suffix == RRRICI { this.DecodeRrrici(word_) } else if this.suffix == ZRRI { this.DecodeZrri(word_) } else if this.suffix == ZRRICI { this.DecodeZrrici(word_) } else if this.suffix == S_RRRI || this.suffix == U_RRRI { this.DecodeSRrri(word_) } else if this.suffix == S_RRRICI || this.suffix == U_RRRICI { this.DecodeSRrrici(word_) } else if this.suffix == RIR { this.DecodeRir(word_) } else if this.suffix == RIRC { this.DecodeRirc(word_) } else if this.suffix == RIRCI { this.DecodeRirci(word_) } else if this.suffix == ZIR { this.DecodeZir(word_) } else if this.suffix == ZIRC { this.DecodeZirc(word_) } else if this.suffix == ZIRCI { this.DecodeZirci(word_) } else if this.suffix == S_RIRC || this.suffix == U_RIRC { this.DecodeSRirc(word_) } else if this.suffix == S_RIRCI || this.suffix == U_RIRCI { this.DecodeSRirci(word_) } else if this.suffix == R { this.DecodeR(word_) } else if this.suffix == RCI { this.DecodeRci(word_) } else if this.suffix == Z { this.DecodeZ(word_) } else if this.suffix == ZCI { this.DecodeZci(word_) } else if this.suffix == S_R || this.suffix == U_R { this.DecodeSR(word_) } else if this.suffix == S_RCI || this.suffix == U_RCI { this.DecodeSRci(word_) } else if this.suffix == CI { this.DecodeCi(word_) } else if this.suffix == I { this.DecodeI(word_) } else if this.suffix == DDCI { this.DecodeDdci(word_) } else if this.suffix == ERRI { this.DecodeErri(word_) } else if this.suffix == S_ERRI || this.suffix == U_ERRI { this.DecodeSErri(word_) } else if this.suffix == EDRI { this.DecodeEdri(word_) } else if this.suffix == ERII { this.DecodeErii(word_) } else if this.suffix == ERIR { this.DecodeErir(word_) } else if this.suffix == ERID { this.DecodeErid(word_) } else if this.suffix == DMA_RRI { this.DecodeDmaRri(word_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Instruction) DecodeRici(word_ *word.Word) { if _, found := this.RiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } if this.suffix != RICI { err := errors.New("suffix is not RICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 16 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 16, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() condition := this.DecodeCondition(word_, condition_begin, condition_end) this.condition = new(cc.Condition) *this.condition = condition pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.SIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != RRI { err := errors.New("suffix is not RRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeRric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != RRIC { err := errors.New("suffix is not RRIC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != RRICI { err := errors.New("suffix is not RRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != RRIF { err := errors.New("suffix is not RRIF") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not RRR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeRrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != RRRC { err := errors.New("suffix is not RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != ZRI { err := errors.New("suffix is not ZRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 28 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 28, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeZric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != ZRIC { err := errors.New("suffix is not RRIC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 11, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != ZRIF { err := errors.New("suffix is not ZRIF") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 27, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != ZRR { err := errors.New("suffix is not ZRR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeZrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRri(word_ *word.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != S_RRI && this.suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeSRric(word_ *word.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != S_RRIC && this.suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrici(word_ *word.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != S_RRICI && this.suffix != U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRrif(word_ *word.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != S_RRIF && this.suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrr(word_ *word.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != S_RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeSRrrc(word_ *word.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != S_RRRC && this.suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrrci(word_ *word.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != S_RRRCI && this.suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != RR { err := errors.New("suffix is not RR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeRrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != RRC { err := errors.New("suffix is not RRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != RRCI { err := errors.New("suffix is not RRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != ZR { err := errors.New("suffix is not ZR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeZrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != ZRC { err := errors.New("suffix is not ZRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRr(word_ *word.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != S_RR && this.suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeSRrc(word_ *word.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != S_RRC && this.suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrci(word_ *word.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != S_RRCI && this.suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeDrdici(word_ *word.Word) { if _, found := this.DrdiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } if this.suffix != DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) db_begin := ra_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) imm_begin := db_end imm_end := imm_begin + 5 imm := this.DecodePc(word_, imm_begin, imm_end) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != RRRI { err := errors.New("suffix is not RRRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) DecodeRrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) DecodeZrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRrri(word_ *word.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != S_RRRI && this.suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) } func (this *Instruction) DecodeSRrrici(word_ *word.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != S_RRRICI && this.suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRir(word_ *word.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != RIR { err := errors.New("suffix is not RIR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeRirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != RIRC { err := errors.New("suffix is not RIRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZir(word_ *word.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != ZIR { err := errors.New("suffix is not ZIR") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 32, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeZirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRirc(word_ *word.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != S_RIRC && this.suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) imm_begin := dc_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRirci(word_ *word.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != S_RIRCI && this.suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) imm_begin := dc_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeR(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != R { err := errors.New("suffix is not R") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) } func (this *Instruction) DecodeRci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != RCI { err := errors.New("suffix is not RCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) condition_begin := rc_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZ(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found && this.op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } if this.suffix != Z { err := errors.New("suffix is not R") panic(err) } } func (this *Instruction) DecodeZci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != ZCI { err := errors.New("suffix is not ZCI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSR(word_ *word.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != S_R && this.suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) } func (this *Instruction) DecodeSRci(word_ *word.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != S_RCI && this.suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) condition_begin := dc_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeCi(word_ *word.Word) { if _, found := this.CiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } if this.suffix != CI { err := errors.New("suffix is not CI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeI(word_ *word.Word) { if _, found := this.IOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } if this.suffix != I { err := errors.New("suffix is not I") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 24, imm) } func (this *Instruction) DecodeDdci(word_ *word.Word) { if _, found := this.DdciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } if this.suffix != DDCI { err := errors.New("suffix is not DDCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) db_begin := dc_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) condition_begin := db_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, word.UNSIGNED) this.pc = new(word.Immediate) this.pc.Init(word.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeErri(word_ *word.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != ERRI { err := errors.New("suffix is not ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) rc_begin := endian_end rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) DecodeSErri(word_ *word.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != S_ERRI && this.suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) DecodeEdri(word_ *word.Word) { if _, found := this.EdriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } if this.suffix != EDRI { err := errors.New("suffix is not EDRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) } func (this *Instruction) DecodeErii(word_ *word.Word) { if _, found := this.EriiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } if this.suffix != ERII { err := errors.New("suffix is not ERII") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) imm_begin := off_end imm_end := imm_begin + 16 imm := this.DecodeImm(word_, imm_begin, imm_end, word.SIGNED) this.imm = new(word.Immediate) this.imm.Init(word.SIGNED, 16, imm) } func (this *Instruction) DecodeErir(word_ *word.Word) { if _, found := this.ErirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } if this.suffix != ERIR { err := errors.New("suffix is not ERIR") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) rb_begin := off_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeErid(word_ *word.Word) { if _, found := this.EridOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } if this.suffix != ERID { err := errors.New("suffix is not ERID") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, word.SIGNED) this.off = new(word.Immediate) this.off.Init(word.SIGNED, 24, off) db_begin := off_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) } func (this *Instruction) DecodeDmaRri(word_ *word.Word) { if _, found := this.DmaRriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } if this.suffix != DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, word.UNSIGNED) this.imm = new(word.Immediate) this.imm.Init(word.UNSIGNED, 8, imm) } func (this *Instruction) DecodeOpCode(word_ *word.Word) OpCode { return OpCode(word_.BitSlice(word.UNSIGNED, this.OpCodeBegin(), this.OpCodeEnd())) } func (this *Instruction) DecodeSuffix(word_ *word.Word) Suffix { return Suffix(word_.BitSlice(word.UNSIGNED, this.SuffixBegin(), this.SuffixEnd())) } func (this *Instruction) DecodeGpRegDescriptor( word_ *word.Word, begin int, end int, ) *reg_descriptor.GpRegDescriptor { index := int(word_.BitSlice(word.UNSIGNED, begin, end)) gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) return gp_reg_descriptor } func (this *Instruction) DecodeSrcRegDescriptor( word_ *word.Word, begin int, end int, ) *reg_descriptor.SrcRegDescriptor { index := int(word_.BitSlice(word.UNSIGNED, begin, end)) config_loader := new(misc.ConfigLoader) config_loader.Init() if index < config_loader.NumGpRegisters() { gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitGpRegDescriptor(gp_reg_descriptor) return src_reg_descriptor } else { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.SpRegDescriptor(index - config_loader.NumGpRegisters()) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } } func (this *Instruction) DecodePairRegDescriptor( word_ *word.Word, begin int, end int, ) *reg_descriptor.PairRegDescriptor { index := int(word_.BitSlice(word.UNSIGNED, begin, end)) pair_reg_descriptor := new(reg_descriptor.PairRegDescriptor) pair_reg_descriptor.Init(index) return pair_reg_descriptor } func (this *Instruction) DecodeImm( word_ *word.Word, begin int, end int, representation word.Representation, ) int64 { return word_.BitSlice(representation, begin, end) } func (this *Instruction) DecodeCondition(word_ *word.Word, begin int, end int) cc.Condition { return cc.Condition(word_.BitSlice(word.UNSIGNED, begin, end)) } func (this *Instruction) DecodePc(word_ *word.Word, begin int, end int) int64 { return this.DecodeImm(word_, begin, end, word.UNSIGNED) } func (this *Instruction) DecodeEndian(word_ *word.Word, begin int, end int) Endian { return Endian(word_.BitSlice(word.UNSIGNED, begin, end)) } func (this *Instruction) DecodeOff( word_ *word.Word, begin int, end int, representation word.Representation, ) int64 { return this.DecodeImm(word_, begin, end, representation) } func (this *Instruction) OpCodeBegin() int { return 0 } func (this *Instruction) OpCodeEnd() int { return this.OpCodeBegin() + this.OpCodeWidth() } func (this *Instruction) OpCodeWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(SDMA)))) } func (this *Instruction) SuffixBegin() int { return this.OpCodeEnd() } func (this *Instruction) SuffixEnd() int { return this.SuffixBegin() + this.SuffixWidth() } func (this *Instruction) SuffixWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(DMA_RRI)))) } func (this *Instruction) RegisterWidth() int { config_loader := new(misc.ConfigLoader) config_loader.Init() return int( math.Ceil( math.Log2(float64(config_loader.NumGpRegisters()) + 1.0 + float64(reg_descriptor.ID8)), ), ) } func (this *Instruction) ConditionWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(cc.LARGE)))) } func (this *Instruction) PcWidth() int { config_loader := new(misc.ConfigLoader) config_loader.Init() return config_loader.AddressWidth() } func (this *Instruction) EndianWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(BIG)))) } func (this *Instruction) AcquireRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ACQUIRE: true, } } func (this *Instruction) ReleaseRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ RELEASE: true, } } func (this *Instruction) BootRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ BOOT: true, RESUME: true, } } func (this *Instruction) RiciOpCodes() map[OpCode]bool { acquire_rici_op_codes := this.AcquireRiciOpCodes() release_rici_op_codes := this.ReleaseRiciOpCodes() boot_rici_op_codes := this.BootRiciOpCodes() rici_op_codes := make(map[OpCode]bool, 0) for k, v := range acquire_rici_op_codes { rici_op_codes[k] = v } for k, v := range release_rici_op_codes { rici_op_codes[k] = v } for k, v := range boot_rici_op_codes { rici_op_codes[k] = v } return rici_op_codes } func (this *Instruction) AddRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, OR: true, XOR: true, } } func (this *Instruction) AsrRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) CallRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ CALL: true, } } func (this *Instruction) RriOpCodes() map[OpCode]bool { add_rri_op_codes := this.AddRriOpCodes() asr_rri_op_codes := this.AsrRriOpCodes() call_rri_op_codes := this.CallRriOpCodes() rri_op_codes := make(map[OpCode]bool, 0) for k, v := range add_rri_op_codes { rri_op_codes[k] = v } for k, v := range asr_rri_op_codes { rri_op_codes[k] = v } for k, v := range call_rri_op_codes { rri_op_codes[k] = v } return rri_op_codes } func (this *Instruction) AddRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) SubRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RricOpCodes() map[OpCode]bool { add_rric_op_codes := this.AddRricOpCodes() asr_rric_op_codes := this.AsrRricOpCodes() sub_rric_op_codes := this.SubRricOpCodes() rric_op_codes := make(map[OpCode]bool, 0) for k, v := range add_rric_op_codes { rric_op_codes[k] = v } for k, v := range asr_rric_op_codes { rric_op_codes[k] = v } for k, v := range sub_rric_op_codes { rric_op_codes[k] = v } return rric_op_codes } func (this *Instruction) AddRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, } } func (this *Instruction) AndRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) SubRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RriciOpCodes() map[OpCode]bool { add_rrici_op_codes := this.AddRriciOpCodes() and_rrici_op_codes := this.AndRriciOpCodes() asr_rrici_op_codes := this.AsrRriciOpCodes() sub_rrici_op_codes := this.SubRriciOpCodes() rrici_op_codes := make(map[OpCode]bool, 0) for k, v := range add_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range and_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range asr_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range sub_rrici_op_codes { rrici_op_codes[k] = v } return rrici_op_codes } func (this *Instruction) RrifOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, SUB: true, SUBC: true, XOR: true, HASH: true, } } func (this *Instruction) RrrOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, ROL: true, ROR: true, RSUB: true, RSUBC: true, SUB: true, SUBC: true, XOR: true, HASH: true, CALL: true, } } func (this *Instruction) AddRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, NAND: true, NOR: true, NXOR: true, ROL: true, ROR: true, OR: true, ORN: true, XOR: true, HASH: true, CALL: true, } } func (this *Instruction) RsubRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ RSUB: true, RSUBC: true, } } func (this *Instruction) SubRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RrrcOpCodes() map[OpCode]bool { add_rrrc_op_codes := this.AddRrrcOpCodes() rsub_rrrc_op_codes := this.RsubRrrcOpCodes() sub_rrrc_op_codes := this.SubRrrcOpCodes() rrrc_op_codes := make(map[OpCode]bool, 0) for k, v := range add_rrrc_op_codes { rrrc_op_codes[k] = v } for k, v := range rsub_rrrc_op_codes { rrrc_op_codes[k] = v } for k, v := range sub_rrrc_op_codes { rrrc_op_codes[k] = v } return rrrc_op_codes } func (this *Instruction) AddRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, } } func (this *Instruction) AndRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) MulRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, } } func (this *Instruction) RsubRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ RSUB: true, RSUBC: true, SUB: true, SUBC: true, } } func (this *Instruction) RrrciOpCodes() map[OpCode]bool { add_rrrci_op_codes := this.AddRrrciOpCodes() and_rrrci_op_codes := this.AndRrrciOpCodes() asr_rrrci_op_codes := this.AsrRrrciOpCodes() mul_rrrci_op_codes := this.MulRrrciOpCodes() rsub_rrrci_op_codes := this.RsubRrrciOpCodes() rrrci_op_codes := make(map[OpCode]bool, 0) for k, v := range add_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range and_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range asr_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range mul_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range rsub_rrrci_op_codes { rrrci_op_codes[k] = v } return rrrci_op_codes } func (this *Instruction) RrOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, TIME_CFG: true, } } func (this *Instruction) RrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, } } func (this *Instruction) CaoRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, } } func (this *Instruction) ExtsbRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, } } func (this *Instruction) TimeCfgRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME_CFG: true, } } func (this *Instruction) RrciOpCodes() map[OpCode]bool { cao_rrci_op_codes := this.CaoRrciOpCodes() extsb_rrci_op_codes := this.ExtsbRrciOpCodes() time_cfg_rrci_op_codes := this.TimeCfgRrciOpCodes() rrci_op_codes := make(map[OpCode]bool, 0) for k, v := range cao_rrci_op_codes { rrci_op_codes[k] = v } for k, v := range extsb_rrci_op_codes { rrci_op_codes[k] = v } for k, v := range time_cfg_rrci_op_codes { rrci_op_codes[k] = v } return rrci_op_codes } func (this *Instruction) DivStepDrdiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ DIV_STEP: true, } } func (this *Instruction) MulStepDrdiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MUL_STEP: true, } } func (this *Instruction) DrdiciOpCodes() map[OpCode]bool { div_step_drdici_op_codes := this.DivStepDrdiciOpCodes() mul_step_drdici_op_codes := this.MulStepDrdiciOpCodes() drdici_op_codes := make(map[OpCode]bool, 0) for k, v := range div_step_drdici_op_codes { drdici_op_codes[k] = v } for k, v := range mul_step_drdici_op_codes { drdici_op_codes[k] = v } return drdici_op_codes } func (this *Instruction) RrriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LSL_ADD: true, LSL_SUB: true, LSR_ADD: true, ROL_ADD: true, } } func (this *Instruction) RrriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ LSL_ADD: true, LSL_SUB: true, LSR_ADD: true, ROL_ADD: true, } } func (this *Instruction) RirOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RircOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RirciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) ROpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME: true, } } func (this *Instruction) RciOpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME: true, } } func (this *Instruction) CiOpCodes() map[OpCode]bool { return map[OpCode]bool{ STOP: true, } } func (this *Instruction) IOpCodes() map[OpCode]bool { return map[OpCode]bool{ FAULT: true, } } func (this *Instruction) MovdDdciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MOVD: true, } } func (this *Instruction) SwapdDdciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SWAPD: true, } } func (this *Instruction) DdciOpCodes() map[OpCode]bool { movd_ddci_op_codes := this.MovdDdciOpCodes() swapd_ddci_op_codes := this.SwapdDdciOpCodes() ddci_op_codes := make(map[OpCode]bool, 0) for k, v := range movd_ddci_op_codes { ddci_op_codes[k] = v } for k, v := range swapd_ddci_op_codes { ddci_op_codes[k] = v } return ddci_op_codes } func (this *Instruction) ErriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LBS: true, LBU: true, LHS: true, LHU: true, LW: true, } } func (this *Instruction) EdriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LD: true, } } func (this *Instruction) EriiOpCodes() map[OpCode]bool { return map[OpCode]bool{ SB: true, SB_ID: true, SD: true, SD_ID: true, SH: true, SH_ID: true, SW: true, SW_ID: true, } } func (this *Instruction) ErirOpCodes() map[OpCode]bool { return map[OpCode]bool{ SB: true, SH: true, SW: true, } } func (this *Instruction) EridOpCodes() map[OpCode]bool { return map[OpCode]bool{ SD: true, } } func (this *Instruction) LdmaDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LDMA: true, } } func (this *Instruction) LdmaiDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LDMAI: true, } } func (this *Instruction) SdmaDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ SDMA: true, } } func (this *Instruction) DmaRriOpCodes() map[OpCode]bool { ldma_dma_rri_op_codes := this.LdmaDmaRriOpCodes() ldmai_dma_rri_op_codes := this.LdmaiDmaRriOpCodes() sdma_dma_rri_op_codes := this.SdmaDmaRriOpCodes() dma_rri_op_codes := make(map[OpCode]bool, 0) for k, v := range ldma_dma_rri_op_codes { dma_rri_op_codes[k] = v } for k, v := range ldmai_dma_rri_op_codes { dma_rri_op_codes[k] = v } for k, v := range sdma_dma_rri_op_codes { dma_rri_op_codes[k] = v } return dma_rri_op_codes } func (this *Instruction) Stringify() string { str := this.StringifyOpCode() + ", " str += this.StringifySuffix() + ", " if this.suffix == RICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == RRIC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRICI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRIF { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == RRRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ZRIC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRIF { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRR { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == ZRRC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRRCI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == S_RRIC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRIF { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == S_RRRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == U_RRIC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRIF { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == U_RRRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == RRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZR { str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == ZRC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRCI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == S_RRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == U_RRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == DRDICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyPairRegDescriptor(this.db) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRRI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == RRRICI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ZRRICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == S_RRRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == U_RRRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RIR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == RIRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RIRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZIR { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == ZIRC { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZIRCI { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RIRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RIRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RIRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RIRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == R { str += this.StringifyGpRegDescriptor(this.rc) } else if this.suffix == RCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == Z { str = str[:len(str)-2] } else if this.suffix == ZCI { str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_R { str += this.StringifyPairRegDescriptor(this.dc) } else if this.suffix == S_RCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_R { str += this.StringifyPairRegDescriptor(this.dc) } else if this.suffix == U_RCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == CI { str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == I { str += this.StringifyImm(this.imm) } else if this.suffix == DDCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyPairRegDescriptor(this.db) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == S_ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == U_ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == EDRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == ERII { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ERIR { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == ERID { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifyPairRegDescriptor(this.db) } else if this.suffix == DMA_RRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else { err := errors.New("suffix is not valid") panic(err) } return str } func (this *Instruction) StringifyOpCode() string { if this.op_code == ACQUIRE { return "acquire" } else if this.op_code == RELEASE { return "release" } else if this.op_code == RELEASE { return "release" } else if this.op_code == ADD { return "add" } else if this.op_code == ADDC { return "addc" } else if this.op_code == AND { return "and" } else if this.op_code == ANDN { return "andn" } else if this.op_code == ASR { return "asr" } else if this.op_code == CAO { return "cao" } else if this.op_code == CLO { return "clo" } else if this.op_code == CLS { return "cls" } else if this.op_code == CLZ { return "clz" } else if this.op_code == CMPB4 { return "cmpb4" } else if this.op_code == DIV_STEP { return "div_step" } else if this.op_code == EXTSB { return "extsb" } else if this.op_code == EXTSH { return "extsh" } else if this.op_code == EXTUB { return "extub" } else if this.op_code == EXTUH { return "extuh" } else if this.op_code == LSL { return "lsl" } else if this.op_code == LSL_ADD { return "lsl_add" } else if this.op_code == LSL_SUB { return "lsl_sub" } else if this.op_code == LSL1 { return "lsl1" } else if this.op_code == LSL1X { return "lsl1x" } else if this.op_code == LSLX { return "lslx" } else if this.op_code == LSR { return "lsr" } else if this.op_code == LSR_ADD { return "lsr_add" } else if this.op_code == LSR1 { return "lsr1" } else if this.op_code == LSR1X { return "lsr1x" } else if this.op_code == LSRX { return "lsrx" } else if this.op_code == MUL_SH_SH { return "mul_sh_sh" } else if this.op_code == MUL_SH_SL { return "mul_sh_sl" } else if this.op_code == MUL_SH_UH { return "mul_sh_uh" } else if this.op_code == MUL_SH_UL { return "mul_sh_ul" } else if this.op_code == MUL_SL_SH { return "mul_sl_sh" } else if this.op_code == MUL_SL_SL { return "mul_sl_sl" } else if this.op_code == MUL_SL_UH { return "mul_sl_uh" } else if this.op_code == MUL_SL_UL { return "mul_sl_ul" } else if this.op_code == MUL_STEP { return "mul_step" } else if this.op_code == MUL_UH_UH { return "mul_uh_uh" } else if this.op_code == MUL_UH_UL { return "mul_uh_ul" } else if this.op_code == MUL_UL_UH { return "mul_ul_uh" } else if this.op_code == MUL_UL_UL { return "mul_ul_ul" } else if this.op_code == NAND { return "nand" } else if this.op_code == NOR { return "nor" } else if this.op_code == NXOR { return "nxor" } else if this.op_code == OR { return "or" } else if this.op_code == ORN { return "orn" } else if this.op_code == ROL { return "rol" } else if this.op_code == ROL_ADD { return "rol_add" } else if this.op_code == ROR { return "ror" } else if this.op_code == RSUB { return "rsub" } else if this.op_code == RSUBC { return "rsubc" } else if this.op_code == SUB { return "sub" } else if this.op_code == SUBC { return "subc" } else if this.op_code == XOR { return "xor" } else if this.op_code == BOOT { return "boot" } else if this.op_code == RESUME { return "resume" } else if this.op_code == STOP { return "stop" } else if this.op_code == CALL { return "call" } else if this.op_code == FAULT { return "fault" } else if this.op_code == NOP { return "nop" } else if this.op_code == SATS { return "sats" } else if this.op_code == MOVD { return "movd" } else if this.op_code == SWAPD { return "swapd" } else if this.op_code == HASH { return "hash" } else if this.op_code == TIME { return "time" } else if this.op_code == TIME_CFG { return "time_cfg" } else if this.op_code == LBS { return "lbs" } else if this.op_code == LBU { return "lbu" } else if this.op_code == LD { return "ld" } else if this.op_code == LHS { return "lhs" } else if this.op_code == LHU { return "lhu" } else if this.op_code == LW { return "lw" } else if this.op_code == SB { return "sb" } else if this.op_code == SB_ID { return "sb_id" } else if this.op_code == SD { return "sd" } else if this.op_code == SD_ID { return "sd_id" } else if this.op_code == SH { return "sh" } else if this.op_code == SH_ID { return "sh_id" } else if this.op_code == SW { return "sw" } else if this.op_code == SW_ID { return "sw_id" } else if this.op_code == LDMA { return "ldma" } else if this.op_code == LDMAI { return "ldmai" } else if this.op_code == SDMA { return "sdma" } else { err := errors.New("op code is not valid") panic(err) } } func (this *Instruction) StringifySuffix() string { if this.suffix == RICI { return "rici" } else if this.suffix == RRI { return "rri" } else if this.suffix == RRIC { return "rric" } else if this.suffix == RRICI { return "rrici" } else if this.suffix == RRIF { return "rrif" } else if this.suffix == RRR { return "rrr" } else if this.suffix == RRRC { return "rrrc" } else if this.suffix == RRRCI { return "rrrci" } else if this.suffix == ZRI { return "zri" } else if this.suffix == ZRIC { return "zric" } else if this.suffix == ZRICI { return "zrici" } else if this.suffix == ZRIF { return "zrif" } else if this.suffix == ZRR { return "zrr" } else if this.suffix == ZRRC { return "zrrc" } else if this.suffix == ZRRCI { return "zrrci" } else if this.suffix == S_RRI { return "s_rri" } else if this.suffix == S_RRIC { return "s_rric" } else if this.suffix == S_RRICI { return "s_rrici" } else if this.suffix == S_RRIF { return "s_rrif" } else if this.suffix == S_RRR { return "s_rrr" } else if this.suffix == S_RRRC { return "s_rrrc" } else if this.suffix == S_RRRCI { return "s_rrrci" } else if this.suffix == U_RRI { return "u_rri" } else if this.suffix == U_RRIC { return "u_rric" } else if this.suffix == U_RRICI { return "u_rrici" } else if this.suffix == U_RRIF { return "u_rrif" } else if this.suffix == U_RRR { return "u_rrr" } else if this.suffix == U_RRRC { return "u_rrrc" } else if this.suffix == U_RRRCI { return "u_rrrci" } else if this.suffix == RR { return "rr" } else if this.suffix == RRC { return "rrc" } else if this.suffix == RRCI { return "rrci" } else if this.suffix == ZR { return "zr" } else if this.suffix == ZRC { return "zrc" } else if this.suffix == ZRCI { return "zrci" } else if this.suffix == S_RR { return "s_rr" } else if this.suffix == S_RRC { return "s_rrc" } else if this.suffix == S_RRCI { return "s_rrci" } else if this.suffix == U_RR { return "u_rr" } else if this.suffix == U_RRC { return "u_rrc" } else if this.suffix == U_RRCI { return "u_rrci" } else if this.suffix == DRDICI { return "drdici" } else if this.suffix == RRRI { return "rrri" } else if this.suffix == RRRICI { return "rrrici" } else if this.suffix == ZRRI { return "zrri" } else if this.suffix == ZRRICI { return "zrrici" } else if this.suffix == S_RRRI { return "s_rrri" } else if this.suffix == S_RRRICI { return "s_rrrici" } else if this.suffix == U_RRRI { return "u_rrri" } else if this.suffix == U_RRRICI { return "u_rrrici" } else if this.suffix == RIR { return "rir" } else if this.suffix == RIRC { return "rirc" } else if this.suffix == RIRCI { return "rirci" } else if this.suffix == ZIR { return "zir" } else if this.suffix == ZIRC { return "zirc" } else if this.suffix == ZIRCI { return "zirci" } else if this.suffix == S_RIRC { return "s_zirc" } else if this.suffix == S_RIRCI { return "s_zirci" } else if this.suffix == U_RIRC { return "u_zirc" } else if this.suffix == U_RIRCI { return "u_zirci" } else if this.suffix == R { return "r" } else if this.suffix == RCI { return "rci" } else if this.suffix == Z { return "z" } else if this.suffix == ZCI { return "zci" } else if this.suffix == S_R { return "s_r" } else if this.suffix == S_RCI { return "s_rci" } else if this.suffix == U_R { return "u_r" } else if this.suffix == U_RCI { return "u_rci" } else if this.suffix == CI { return "ci" } else if this.suffix == I { return "i" } else if this.suffix == DDCI { return "ddci" } else if this.suffix == ERRI { return "erri" } else if this.suffix == S_ERRI { return "s_erri" } else if this.suffix == U_ERRI { return "u_erri" } else if this.suffix == EDRI { return "edri" } else if this.suffix == ERII { return "erii" } else if this.suffix == ERIR { return "erir" } else if this.suffix == ERID { return "erid" } else if this.suffix == DMA_RRI { return "dma_rri" } else { err := errors.New("suffix is not valid") panic(err) } } func (this *Instruction) StringifyGpRegDescriptor( gp_reg_descriptor *reg_descriptor.GpRegDescriptor, ) string { return "r" + strconv.Itoa(gp_reg_descriptor.Index()) } func (this *Instruction) StringifySrcRegDescriptor( src_reg_descriptor *reg_descriptor.SrcRegDescriptor, ) string { if src_reg_descriptor.IsGpRegDescriptor() { return this.StringifyGpRegDescriptor(src_reg_descriptor.GpRegDescriptor()) } else { sp_reg_descriptor := src_reg_descriptor.SpRegDescriptor() if *sp_reg_descriptor == reg_descriptor.ZERO { return "zero" } else if *sp_reg_descriptor == reg_descriptor.ONE { return "one" } else if *sp_reg_descriptor == reg_descriptor.LNEG { return "lneg" } else if *sp_reg_descriptor == reg_descriptor.MNEG { return "mneg" } else if *sp_reg_descriptor == reg_descriptor.ID { return "id" } else if *sp_reg_descriptor == reg_descriptor.ID2 { return "id2" } else if *sp_reg_descriptor == reg_descriptor.ID4 { return "id4" } else if *sp_reg_descriptor == reg_descriptor.ID8 { return "id8" } else { err := errors.New("sp reg descriptor is not valid") panic(err) } } } func (this *Instruction) StringifyPairRegDescriptor( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, ) string { return "d" + strconv.Itoa(pair_reg_descriptor.Index()) } func (this *Instruction) StringifyImm(imm *word.Immediate) string { return strconv.FormatInt(imm.Value(), 10) } func (this *Instruction) StringifyCondition(condition cc.Condition) string { if condition == cc.TRUE { return "true" } else if condition == cc.FALSE { return "false" } else if condition == cc.Z { return "z" } else if condition == cc.NZ { return "nz" } else if condition == cc.E { return "e" } else if condition == cc.O { return "o" } else if condition == cc.PL { return "pl" } else if condition == cc.MI { return "mi" } else if condition == cc.OV { return "ov" } else if condition == cc.NOV { return "nov" } else if condition == cc.C { return "c" } else if condition == cc.NC { return "nc" } else if condition == cc.SZ { return "sz" } else if condition == cc.SNZ { return "snz" } else if condition == cc.SPL { return "spl" } else if condition == cc.SMI { return "smi" } else if condition == cc.SO { return "so" } else if condition == cc.SE { return "se" } else if condition == cc.NC5 { return "nc5" } else if condition == cc.NC6 { return "nc6" } else if condition == cc.NC7 { return "nc7" } else if condition == cc.NC8 { return "nc8" } else if condition == cc.NC9 { return "nc9" } else if condition == cc.NC10 { return "nc10" } else if condition == cc.NC11 { return "nc11" } else if condition == cc.NC12 { return "nc12" } else if condition == cc.NC13 { return "nc13" } else if condition == cc.NC14 { return "nc14" } else if condition == cc.MAX { return "max" } else if condition == cc.NMAX { return "nmax" } else if condition == cc.SH32 { return "sh32" } else if condition == cc.NSH32 { return "nsh32" } else if condition == cc.EQ { return "eq" } else if condition == cc.NEQ { return "neq" } else if condition == cc.LTU { return "ltu" } else if condition == cc.LEU { return "leu" } else if condition == cc.GTU { return "gtu" } else if condition == cc.GEU { return "geu" } else if condition == cc.LTS { return "lts" } else if condition == cc.LES { return "les" } else if condition == cc.GTS { return "gts" } else if condition == cc.GES { return "ges" } else if condition == cc.XZ { return "xz" } else if condition == cc.XNZ { return "xnz" } else if condition == cc.XLEU { return "xleu" } else if condition == cc.XGTU { return "xgtu" } else if condition == cc.XLES { return "xles" } else if condition == cc.XGTS { return "xgts" } else if condition == cc.SMALL { return "small" } else if condition == cc.LARGE { return "large" } else { err := errors.New("condition is not valid") panic(err) } } func (this *Instruction) StringifyEndian(endian Endian) string { if endian == LITTLE { return "!little" } else if endian == BIG { return "!big" } else { err := errors.New("endian is not valid") panic(err) } } func (this *Instruction) StringifyOff(off *word.Immediate) string { return strconv.FormatInt(off.Value(), 10) } func (this *Instruction) StringifyPc(pc *word.Immediate) string { return strconv.FormatInt(pc.Value(), 10) } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/op_code.go ================================================ package instruction type OpCode int const ( ACQUIRE OpCode = iota RELEASE ADD ADDC AND ANDN ASR CAO CLO CLS CLZ CMPB4 DIV_STEP EXTSB EXTSH EXTUB EXTUH LSL LSL_ADD LSL_SUB LSL1 LSL1X LSLX LSR LSR_ADD LSR1 LSR1X LSRX MUL_SH_SH MUL_SH_SL MUL_SH_UH MUL_SH_UL MUL_SL_SH MUL_SL_SL MUL_SL_UH MUL_SL_UL MUL_STEP MUL_UH_UH MUL_UH_UL MUL_UL_UH MUL_UL_UL NAND NOR NXOR OR ORN ROL ROL_ADD ROR RSUB RSUBC SUB SUBC XOR BOOT RESUME STOP CALL FAULT NOP SATS MOVD SWAPD HASH TIME TIME_CFG LBS LBU LD LHS LHU LW SB SB_ID SD SD_ID SH SH_ID SW SW_ID LDMA LDMAI SDMA ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/reg_descriptor/gp_reg_descriptor.go ================================================ package reg_descriptor import ( "errors" "uPIMulator/src/misc" ) type GpRegDescriptor struct { index int } func (this *GpRegDescriptor) Init(index int) { if index < 0 { err := errors.New("index < 0") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() if index >= config_loader.NumGpRegisters() { err := errors.New("index >= num gp registers") panic(err) } this.index = index } func (this *GpRegDescriptor) Index() int { return this.index } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/reg_descriptor/pair_reg_descriptor.go ================================================ package reg_descriptor import ( "errors" ) type PairRegDescriptor struct { even_reg_descriptor *GpRegDescriptor odd_reg_descriptor *GpRegDescriptor } func (this *PairRegDescriptor) Init(index int) { if index%2 != 0 { err := errors.New("index %2 != 0") panic(err) } this.even_reg_descriptor = new(GpRegDescriptor) this.even_reg_descriptor.Init(index) this.odd_reg_descriptor = new(GpRegDescriptor) this.odd_reg_descriptor.Init(index + 1) } func (this *PairRegDescriptor) Index() int { return this.even_reg_descriptor.Index() } func (this *PairRegDescriptor) EvenRegDescriptor() *GpRegDescriptor { return this.even_reg_descriptor } func (this *PairRegDescriptor) OddRegDescriptor() *GpRegDescriptor { return this.odd_reg_descriptor } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/reg_descriptor/sp_reg_descriptor.go ================================================ package reg_descriptor type SpRegDescriptor int const ( ZERO SpRegDescriptor = iota ONE LNEG MNEG ID ID2 ID4 ID8 ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/reg_descriptor/src_reg_descriptor.go ================================================ package reg_descriptor type SrcRegDescriptor struct { gp_reg_descriptor *GpRegDescriptor sp_reg_descriptor *SpRegDescriptor } func (this *SrcRegDescriptor) InitGpRegDescriptor(gp_reg_descriptor *GpRegDescriptor) { this.gp_reg_descriptor = gp_reg_descriptor this.sp_reg_descriptor = nil } func (this *SrcRegDescriptor) InitSpRegDescriptor(sp_reg_descriptor *SpRegDescriptor) { this.gp_reg_descriptor = nil this.sp_reg_descriptor = sp_reg_descriptor } func (this *SrcRegDescriptor) IsGpRegDescriptor() bool { return this.gp_reg_descriptor != nil } func (this *SrcRegDescriptor) IsSpRegDescriptor() bool { return this.sp_reg_descriptor != nil } func (this *SrcRegDescriptor) GpRegDescriptor() *GpRegDescriptor { return this.gp_reg_descriptor } func (this *SrcRegDescriptor) SpRegDescriptor() *SpRegDescriptor { return this.sp_reg_descriptor } ================================================ FILE: golang/uPIMulator/src/linker/kernel/instruction/suffix.go ================================================ package instruction type Suffix int const ( RICI Suffix = iota RRI RRIC RRICI RRIF RRR RRRC RRRCI ZRI ZRIC ZRICI ZRIF ZRR ZRRC ZRRCI S_RRI S_RRIC S_RRICI S_RRIF S_RRR S_RRRC S_RRRCI U_RRI U_RRIC U_RRICI U_RRIF U_RRR U_RRRC U_RRRCI RR RRC RRCI ZR ZRC ZRCI S_RR S_RRC S_RRCI U_RR U_RRC U_RRCI DRDICI RRRI RRRICI ZRRI ZRRICI S_RRRI S_RRRICI U_RRRI U_RRRICI RIR RIRC RIRCI ZIR ZIRC ZIRCI S_RIRC S_RIRCI U_RIRC U_RIRCI R RCI Z ZCI S_R S_RCI U_R U_RCI CI I DDCI ERRI S_ERRI U_ERRI EDRI ERII ERIR ERID DMA_RRI ) ================================================ FILE: golang/uPIMulator/src/linker/kernel/kernel.go ================================================ package kernel import ( "errors" "uPIMulator/src/abi/encoding" ) type Kernel struct { addresses map[string]int64 atomic *encoding.ByteStream iram *encoding.ByteStream wram *encoding.ByteStream mram *encoding.ByteStream } func (this *Kernel) Init() { this.addresses = make(map[string]int64, 0) } func (this *Kernel) Address(label_name string) int64 { if address, found := this.addresses[label_name]; found { return address } else { err := errors.New("address is not found") panic(err) } } func (this *Kernel) Atomic() *encoding.ByteStream { return this.atomic } func (this *Kernel) SetAtomic(atomic *encoding.ByteStream) { this.atomic = atomic } func (this *Kernel) Iram() *encoding.ByteStream { return this.iram } func (this *Kernel) SetIram(iram *encoding.ByteStream) { this.iram = iram } func (this *Kernel) Wram() *encoding.ByteStream { return this.wram } func (this *Kernel) SetWram(wram *encoding.ByteStream) { this.wram = wram } func (this *Kernel) Mram() *encoding.ByteStream { return this.mram } func (this *Kernel) SetMram(mram *encoding.ByteStream) { this.mram = mram } ================================================ FILE: golang/uPIMulator/src/linker/kernel/label.go ================================================ package kernel import ( "errors" "uPIMulator/src/abi/encoding" ) type Label struct { name string address *int64 size int64 byte_stream *encoding.ByteStream } func (this *Label) Init(name string) { this.name = name this.address = nil this.size = 0 this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() } func (this *Label) Name() string { return this.name } func (this *Label) Address() int64 { if this.address == nil { err := errors.New("address is not yet set") panic(err) } return *this.address } func (this *Label) BeginAddress() int64 { return this.Address() } func (this *Label) EndAddress() int64 { return this.Address() + this.Size() } func (this *Label) SetAddress(address int64) { if this.address != nil { err := errors.New("address is already set") panic(err) } this.address = new(int64) *this.address = address } func (this *Label) Size() int64 { return this.size } func (this *Label) SetSize(size int64) { this.size = size } func (this *Label) ToByteStream() *encoding.ByteStream { if this.size != this.byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } return this.byte_stream } func (this *Label) Append(encodable Encodable) { this.byte_stream.Merge(encodable.Encode()) if this.byte_stream.Size() > this.size { err := errors.New("byte stream's size > size") panic(err) } } ================================================ FILE: golang/uPIMulator/src/linker/kernel/liveness.go ================================================ package kernel type Liveness struct { defs map[string]bool uses map[string]bool global_symbols map[string]bool } func (this *Liveness) Init() { this.defs = make(map[string]bool, 0) this.uses = make(map[string]bool, 0) this.global_symbols = make(map[string]bool, 0) } func (this *Liveness) Defs() map[string]bool { return this.defs } func (this *Liveness) AddDef(def string) { this.defs[def] = true } func (this *Liveness) Uses() map[string]bool { return this.uses } func (this *Liveness) AddUse(use string) { this.uses[use] = true } func (this *Liveness) GlobalSymbols() map[string]bool { return this.global_symbols } func (this *Liveness) AddGlobalSymbol(global_symbol string) { this.global_symbols[global_symbol] = true } func (this *Liveness) LocalSymbols() map[string]bool { local_symbols := make(map[string]bool, 0) for def, _ := range this.defs { if _, found := this.global_symbols[def]; !found { local_symbols[def] = true } } return local_symbols } func (this *Liveness) UnresolvedSymbols() map[string]bool { unresolved_symbols := make(map[string]bool, 0) for use, _ := range this.uses { if _, found := this.defs[use]; !found { unresolved_symbols[use] = true } } return unresolved_symbols } ================================================ FILE: golang/uPIMulator/src/linker/kernel/relocatable.go ================================================ package kernel import ( "errors" "strings" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/misc" ) type Relocatable struct { name string path string token_stream *lexer.TokenStream ast *parser.Ast liveness *Liveness renames map[string]string } func (this *Relocatable) Init(name string) { this.name = name this.renames = make(map[string]string, 0) } func (this *Relocatable) Name() string { return this.name } func (this *Relocatable) Path() string { return this.path } func (this *Relocatable) SetPath(path string) { this.path = path } func (this *Relocatable) TokenStream() *lexer.TokenStream { return this.token_stream } func (this *Relocatable) SetTokenStream(token_stream *lexer.TokenStream) { this.token_stream = token_stream } func (this *Relocatable) Ast() *parser.Ast { return this.ast } func (this *Relocatable) SetAst(ast *parser.Ast) { this.ast = ast } func (this *Relocatable) Liveness() *Liveness { return this.liveness } func (this *Relocatable) SetLiveness(liveness *Liveness) { this.liveness = liveness } func (this *Relocatable) Lines() []string { file_scanner := new(misc.FileScanner) file_scanner.Init(this.path) lines := file_scanner.ReadLines() for i, line := range lines { lines[i] = this.RenameLine(line) } return lines } func (this *Relocatable) RenameLocalSymbol(old_name string, new_name string) { if _, found := this.liveness.LocalSymbols()[old_name]; !found { err := errors.New("local symbol is not found") panic(err) } if rename, found := this.renames[old_name]; found { if rename != new_name { err := errors.New("rename is already set") panic(err) } } this.renames[old_name] = new_name } func (this *Relocatable) RenameLine(line string) string { for old_name, new_name := range this.renames { line = strings.ReplaceAll(line, old_name+",", new_name+",") line = strings.ReplaceAll(line, old_name+" ", new_name+" ") line = strings.ReplaceAll(line, old_name+"\t", new_name+"\t") line = strings.ReplaceAll(line, old_name+":", new_name+":") line = strings.ReplaceAll(line, old_name+"+", new_name+"+") line = strings.ReplaceAll(line, old_name+"-", new_name+"-") if len(line) > len(old_name) { pos := len(line) - len(old_name) if line[pos:] == old_name { line = line[:pos] + new_name } } } return line } ================================================ FILE: golang/uPIMulator/src/linker/kernel/section.go ================================================ package kernel import ( "errors" "uPIMulator/src/abi/encoding" ) type SectionName int const ( ATOMIC SectionName = iota BSS DATA DEBUG_ABBREV DEBUG_FRAME DEBUG_INFO DEBUG_LINE DEBUG_LOC DEBUG_RANGES DEBUG_STR DPU_HOST MRAM RODATA STACK_SIZES TEXT ) type SectionFlag int const ( ALLOC SectionFlag = iota WRITE EXECINSTR LINK_ORDER MERGE STRINGS ) type SectionType int const ( PROGBITS SectionType = iota NOBITS ) type Section struct { section_name SectionName name string section_flags map[SectionFlag]bool section_type SectionType labels []*Label cur_label *Label } func (this *Section) Init( section_name SectionName, name string, section_flags map[SectionFlag]bool, section_type SectionType, ) { this.section_name = section_name this.name = name this.section_flags = section_flags this.section_type = section_type default_label := new(Label) default_label.Init(this.HiddenLabelName()) this.labels = make([]*Label, 0) this.labels = append(this.labels, default_label) this.cur_label = default_label } func (this *Section) SectionName() SectionName { return this.section_name } func (this *Section) Name() string { return this.name } func (this *Section) SectionFlags() map[SectionFlag]bool { return this.section_flags } func (this *Section) SectionType() SectionType { return this.section_type } func (this *Section) Address() int64 { return this.labels[0].Address() } func (this *Section) SetAddress(address int64) { cur_address := address for _, label := range this.labels { label.SetAddress(cur_address) cur_address += label.Size() } } func (this *Section) Size() int64 { size := int64(0) for _, label := range this.labels { size += label.Size() } return size } func (this *Section) Label(label_name string) *Label { for _, label := range this.labels { if label.Name() == label_name { return label } } return nil } func (this *Section) Labels() []*Label { return this.labels } func (this *Section) AppendLabel(label_name string) { label := new(Label) label.Init(label_name) this.labels = append(this.labels, label) } func (this *Section) CheckoutLabel(label_name string) { if this.Label(label_name) == nil { err := errors.New("label is not found") panic(err) } this.cur_label = this.Label(label_name) } func (this *Section) CurLabel() *Label { return this.cur_label } func (this *Section) ToByteStream() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, label := range this.labels { byte_stream.Merge(label.ToByteStream()) } return byte_stream } func (this *Section) HiddenLabelName() string { if this.section_name == ATOMIC { return "atomic." + this.name } else if this.section_name == BSS { return "bss." + this.name } else if this.section_name == DATA { return "data." + this.name } else if this.section_name == DEBUG_ABBREV { return "debug_abbrev." + this.name } else if this.section_name == DEBUG_FRAME { return "debug_frame." + this.name } else if this.section_name == DEBUG_INFO { return "debug_info." + this.name } else if this.section_name == DEBUG_LINE { return "debug_line." + this.name } else if this.section_name == DEBUG_LOC { return "debug_loc." + this.name } else if this.section_name == DEBUG_RANGES { return "debug_ranges." + this.name } else if this.section_name == DEBUG_STR { return "debug_str." + this.name } else if this.section_name == DPU_HOST { return "dpu_host." + this.name } else if this.section_name == MRAM { return "mram." + this.name } else if this.section_name == RODATA { return "rodata." + this.name } else if this.section_name == STACK_SIZES { return "stack_sizes." + this.name } else if this.section_name == TEXT { return "text." + this.name } else { err := errors.New("section name is not valid") panic(err) } } ================================================ FILE: golang/uPIMulator/src/linker/lex_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/lexer" ) type LexJob struct { relocatable *kernel.Relocatable } func (this *LexJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *LexJob) Execute() { fmt.Printf("Lexing %s...\n", this.relocatable.Path()) lexer_ := new(lexer.Lexer) lexer_.Init() token_stream := lexer_.Lex(this.relocatable.Path()) this.relocatable.SetTokenStream(token_stream) } ================================================ FILE: golang/uPIMulator/src/linker/lexer/keyword_factory.go ================================================ package lexer import ( "errors" ) type KeywordFactory struct { keywords map[string]TokenType } func (this *KeywordFactory) Init() { this.keywords = make(map[string]TokenType, 0) } func (this *KeywordFactory) AddKeyword(keyword string, token_type TokenType) { this.keywords[keyword] = token_type } func (this *KeywordFactory) IsTokenizable(word string) bool { _, found := this.keywords[word] return found } func (this *KeywordFactory) Tokenize(word string) *Token { if _, found := this.keywords[word]; !found { err := errors.New("word is not tokenizable") panic(err) } token_type := this.keywords[word] token := new(Token) token.Init(token_type, "") return token } ================================================ FILE: golang/uPIMulator/src/linker/lexer/lexer.go ================================================ package lexer import ( "errors" "uPIMulator/src/misc" ) type Lexer struct { tokenizer *Tokenizer } func (this *Lexer) Init() { this.tokenizer = new(Tokenizer) this.tokenizer.Init() } func (this *Lexer) Lex(path string) *TokenStream { file_scanner := new(misc.FileScanner) file_scanner.Init(path) token_stream := new(TokenStream) token_stream.Init() for _, line := range file_scanner.ReadLines() { token_stream.Merge(this.Tokenize(line)) new_line := new(Token) new_line.Init(NEW_LINE, "") token_stream.Append(new_line) } end_of_file := new(Token) end_of_file.Init(END_OF_FILE, "") token_stream.Append(end_of_file) return token_stream } func (this *Lexer) Tokenize(line string) *TokenStream { token_stream := new(TokenStream) token_stream.Init() prev_pos := 0 for prev_pos < len(line) { token, length := this.FindTokenWithMaxLength(line, prev_pos) if token != nil { token_stream.Append(token) } prev_pos += length } return token_stream } func (this *Lexer) FindTokenWithMaxLength(line string, prev_pos int) (*Token, int) { if prev_pos < 0 { err := errors.New("prev pos < 0") panic(err) } if this.IsWhiteSpace(string(line[prev_pos])) { return nil, 1 } if prev_pos+2 < len(line) && this.IsComment(line[prev_pos:prev_pos+2]) { return nil, len(line) - prev_pos } if this.IsQuote(string(line[prev_pos])) { next_quote_pos := this.FindNextQuote(line, prev_pos+1) word := line[prev_pos : next_quote_pos+1] token := this.tokenizer.Tokenize(word) return token, next_quote_pos - prev_pos + 1 } for i := prev_pos + 1; i <= len(line); i++ { word := line[prev_pos:i] if i+1 <= len(line) { next_word := line[prev_pos : i+1] if this.tokenizer.IsTokenizable(word) && !this.tokenizer.IsTokenizable(next_word) { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } else { continue } } else { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } } err := errors.New("line is not further tokenizable") panic(err) } func (this *Lexer) IsWhiteSpace(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == " " || word == "\t" || word == "\n" } func (this *Lexer) IsComment(word string) bool { if len(word) != 2 { err := errors.New("word size != 2") panic(err) } return word == "//" } func (this *Lexer) IsQuote(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == "\"" } func (this *Lexer) FindNextQuote(line string, pos int) int { for i := pos; i < len(line); i++ { if this.IsQuote(string(line[i])) { return i } } err := errors.New("line does not have the next quote") panic(err) } ================================================ FILE: golang/uPIMulator/src/linker/lexer/regex.go ================================================ package lexer import ( "errors" "regexp" ) type Regex struct { expr string regex *regexp.Regexp token_type TokenType } func (this *Regex) Init(expr string, token_type TokenType) { this.expr = expr regex, err := regexp.Compile(expr) if err != nil { panic(err) } this.regex = regex this.token_type = token_type } func (this *Regex) Expr() string { return this.expr } func (this *Regex) TokenType() TokenType { return this.token_type } func (this *Regex) IsTokenizable(word string) bool { return this.regex.MatchString(word) } func (this *Regex) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not matched") panic(err) } token := new(Token) token.Init(this.token_type, word) return token } ================================================ FILE: golang/uPIMulator/src/linker/lexer/regex_factory.go ================================================ package lexer import ( "errors" ) type RegexFactory struct { regexes []*Regex } func (this *RegexFactory) Init() { this.regexes = make([]*Regex, 0) } func (this *RegexFactory) HasRegex(expr string) bool { for _, regex := range this.regexes { if regex.Expr() == expr { return true } } return false } func (this *RegexFactory) AddRegex(expr string, token_type TokenType) { if this.HasRegex(expr) { err := errors.New("regex already exists") panic(err) } regex := new(Regex) regex.Init(expr, token_type) this.regexes = append(this.regexes, regex) } func (this *RegexFactory) IsTokenizable(word string) bool { for _, regex := range this.regexes { if regex.IsTokenizable(word) { return true } } return false } func (this *RegexFactory) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not tokenizable") panic(err) } for _, regex := range this.regexes { if regex.IsTokenizable(word) { token := new(Token) token.Init(regex.TokenType(), word) return token } } return nil } ================================================ FILE: golang/uPIMulator/src/linker/lexer/token.go ================================================ package lexer type TokenType int const ( END_OF_FILE TokenType = iota NEW_LINE IDENTIFIER POSITIVIE_NUMBER HEX_NUMBER STRING GP_REG PAIR_REG ACQUIRE RELEASE BOOT RESUME ADD ADDC AND ANDN ASR CMPB4 LSL LSL1 LSL1X LSLX LSR LSR1 LSR1X LSRX MUL_SH_SH MUL_SH_SL MUL_SH_UH MUL_SH_UL MUL_SL_SH MUL_SL_SL MUL_SL_UH MUL_SL_UL MUL_UH_UH MUL_UH_UL MUL_UL_UH MUL_UL_UL NAND NOR NXOR OR ORN ROL ROR RSUB RSUBC SUB SUBC XOR CALL HASH CAO CLO CLS CLZ EXTSB EXTSH EXTUB EXTUH SATS TIME_CFG DIV_STEP MUL_STEP LSL_ADD LSL_SUB LSR_ADD ROL_ADD TIME NOP STOP FAULT MOVD SWAPD LBS LBU LD LHS LHU LW SB SB_ID SD SD_ID SH SH_ID SW SW_ID LDMA LDMAI SDMA MOVE NEG NOT BKP JEQ JNEQ JZ JNZ JLTU JGTU JLEU JGEU JLTS JGTS JLES JGES JUMP S U ATOMIC BSS DATA DEBUG_ABBREV DEBUG_FRAME DEBUG_INFO DEBUG_LINE DEBUG_LOC DEBUG_RANGES DEBUG_STR DPU_HOST MRAM RODATA STACK_SIZES TEXT PROGBITS NOBITS FUNCTION OBJECT TRUE FALSE Z NZ E O PL MI OV NOV C NC SZ SNZ SPL SMI SO SE NC5 NC6 NC7 NC8 NC9 NC10 NC11 NC12 NC13 NC14 MAX NMAX SH32 NSH32 EQ NEQ LTU LEU GTU GEU LTS LES GTS GES XZ XNZ XLEU XGTU XLES XGTS SMALL LARGE LITTLE BIG ZERO_REG ONE ID ID2 ID4 ID8 LNEG MNEG ADDRSIG ADDRSIG_SYM ASCII ASCIZ BYTE CFI_DEF_CFA_OFFSET CFI_ENDPROC CFI_OFFSET CFI_SECTIONS CFI_STARTPROC FILE GLOBL LOC LONG P2ALIGN QUAD SECTION SET SHORT SIZE TYPE WEAK ZERO_DIRECTIVE IS_STMT PROLOGUE_END COLON COMMA PLUS MINUS ) type Token struct { token_type TokenType attribute string } func (this *Token) Init(token_type TokenType, attribute string) { this.token_type = token_type this.attribute = attribute } func (this *Token) TokenType() TokenType { return this.token_type } func (this *Token) Attribute() string { return this.attribute } ================================================ FILE: golang/uPIMulator/src/linker/lexer/token_stream.go ================================================ package lexer type TokenStream struct { tokens []*Token } func (this *TokenStream) Init() { this.tokens = make([]*Token, 0) } func (this *TokenStream) Size() int { return len(this.tokens) } func (this *TokenStream) Get(pos int) *Token { return this.tokens[pos] } func (this *TokenStream) Append(token *Token) { this.tokens = append(this.tokens, token) } func (this *TokenStream) Merge(token_stream *TokenStream) { for i := 0; i < token_stream.Size(); i++ { this.Append(token_stream.Get(i)) } } ================================================ FILE: golang/uPIMulator/src/linker/lexer/tokenizer.go ================================================ package lexer import ( "errors" ) type Tokenizer struct { keyword_factory *KeywordFactory regex_factory *RegexFactory } func (this *Tokenizer) Init() { this.InitKeywordFactory() this.InitRegexFactory() } func (this *Tokenizer) InitKeywordFactory() { this.keyword_factory = new(KeywordFactory) this.keyword_factory.Init() this.keyword_factory.AddKeyword("acquire", ACQUIRE) this.keyword_factory.AddKeyword("release", RELEASE) this.keyword_factory.AddKeyword("boot", BOOT) this.keyword_factory.AddKeyword("resume", RESUME) this.keyword_factory.AddKeyword("add", ADD) this.keyword_factory.AddKeyword("addc", ADDC) this.keyword_factory.AddKeyword("and", AND) this.keyword_factory.AddKeyword("andn", ANDN) this.keyword_factory.AddKeyword("asr", ASR) this.keyword_factory.AddKeyword("cmpb4", CMPB4) this.keyword_factory.AddKeyword("lsl", LSL) this.keyword_factory.AddKeyword("lsl1", LSL1) this.keyword_factory.AddKeyword("lsl1x", LSL1X) this.keyword_factory.AddKeyword("lslx", LSLX) this.keyword_factory.AddKeyword("lsr", LSR) this.keyword_factory.AddKeyword("lsr1", LSR1) this.keyword_factory.AddKeyword("lsr1x", LSR1X) this.keyword_factory.AddKeyword("lsrx", LSRX) this.keyword_factory.AddKeyword("mul_sh_sh", MUL_SH_SH) this.keyword_factory.AddKeyword("mul_sh_sl", MUL_SH_SL) this.keyword_factory.AddKeyword("mul_sh_uh", MUL_SH_UH) this.keyword_factory.AddKeyword("mul_sh_ul", MUL_SH_UL) this.keyword_factory.AddKeyword("mul_sl_sh", MUL_SL_SH) this.keyword_factory.AddKeyword("mul_sl_sl", MUL_SL_SL) this.keyword_factory.AddKeyword("mul_sl_uh", MUL_SL_UH) this.keyword_factory.AddKeyword("mul_sl_ul", MUL_SL_UL) this.keyword_factory.AddKeyword("mul_uh_uh", MUL_UH_UH) this.keyword_factory.AddKeyword("mul_uh_ul", MUL_UH_UL) this.keyword_factory.AddKeyword("mul_ul_uh", MUL_UL_UH) this.keyword_factory.AddKeyword("mul_ul_ul", MUL_UL_UL) this.keyword_factory.AddKeyword("nand", NAND) this.keyword_factory.AddKeyword("nor", NOR) this.keyword_factory.AddKeyword("nxor", NXOR) this.keyword_factory.AddKeyword("or", OR) this.keyword_factory.AddKeyword("orn", ORN) this.keyword_factory.AddKeyword("rol", ROL) this.keyword_factory.AddKeyword("ror", ROR) this.keyword_factory.AddKeyword("rsub", RSUB) this.keyword_factory.AddKeyword("rsubc", RSUBC) this.keyword_factory.AddKeyword("sub", SUB) this.keyword_factory.AddKeyword("subc", SUBC) this.keyword_factory.AddKeyword("xor", XOR) this.keyword_factory.AddKeyword("call", CALL) this.keyword_factory.AddKeyword("hash", HASH) this.keyword_factory.AddKeyword("cao", CAO) this.keyword_factory.AddKeyword("clo", CLO) this.keyword_factory.AddKeyword("cls", CLS) this.keyword_factory.AddKeyword("clz", CLZ) this.keyword_factory.AddKeyword("extsb", EXTSB) this.keyword_factory.AddKeyword("extsh", EXTSH) this.keyword_factory.AddKeyword("extub", EXTUB) this.keyword_factory.AddKeyword("extuh", EXTUH) this.keyword_factory.AddKeyword("sats", SATS) this.keyword_factory.AddKeyword("time_cfg", TIME_CFG) this.keyword_factory.AddKeyword("div_step", DIV_STEP) this.keyword_factory.AddKeyword("mul_step", MUL_STEP) this.keyword_factory.AddKeyword("lsl_add", LSL_ADD) this.keyword_factory.AddKeyword("lsl_sub", LSL_SUB) this.keyword_factory.AddKeyword("lsr_add", LSR_ADD) this.keyword_factory.AddKeyword("rol_add", ROL_ADD) this.keyword_factory.AddKeyword("time", TIME) this.keyword_factory.AddKeyword("nop", NOP) this.keyword_factory.AddKeyword("stop", STOP) this.keyword_factory.AddKeyword("fault", FAULT) this.keyword_factory.AddKeyword("movd", MOVD) this.keyword_factory.AddKeyword("swapd", SWAPD) this.keyword_factory.AddKeyword("lbs", LBS) this.keyword_factory.AddKeyword("lbu", LBU) this.keyword_factory.AddKeyword("ld", LD) this.keyword_factory.AddKeyword("lhs", LHS) this.keyword_factory.AddKeyword("lhu", LHU) this.keyword_factory.AddKeyword("lw", LW) this.keyword_factory.AddKeyword("sb", SB) this.keyword_factory.AddKeyword("sb_id", SB_ID) this.keyword_factory.AddKeyword("sd", SD) this.keyword_factory.AddKeyword("sd_id", SD_ID) this.keyword_factory.AddKeyword("sh", SH) this.keyword_factory.AddKeyword("sh_id", SH_ID) this.keyword_factory.AddKeyword("sw", SW) this.keyword_factory.AddKeyword("sw_id", SW_ID) this.keyword_factory.AddKeyword("ldma", LDMA) this.keyword_factory.AddKeyword("ldmai", LDMAI) this.keyword_factory.AddKeyword("sdma", SDMA) this.keyword_factory.AddKeyword("move", MOVE) this.keyword_factory.AddKeyword("neg", NEG) this.keyword_factory.AddKeyword("not", NOT) this.keyword_factory.AddKeyword("bkp", BKP) this.keyword_factory.AddKeyword("jeq", JEQ) this.keyword_factory.AddKeyword("jneq", JNEQ) this.keyword_factory.AddKeyword("jz", JZ) this.keyword_factory.AddKeyword("jnz", JNZ) this.keyword_factory.AddKeyword("jltu", JLTU) this.keyword_factory.AddKeyword("jgtu", JGTU) this.keyword_factory.AddKeyword("jleu", JLEU) this.keyword_factory.AddKeyword("jgeu", JGEU) this.keyword_factory.AddKeyword("jlts", JLTS) this.keyword_factory.AddKeyword("jgts", JGTS) this.keyword_factory.AddKeyword("jles", JLES) this.keyword_factory.AddKeyword("jges", JGES) this.keyword_factory.AddKeyword("jump", JUMP) this.keyword_factory.AddKeyword(".s", S) this.keyword_factory.AddKeyword(".u", U) this.keyword_factory.AddKeyword(".atomic", ATOMIC) this.keyword_factory.AddKeyword(".bss", BSS) this.keyword_factory.AddKeyword(".data", DATA) this.keyword_factory.AddKeyword(".debug_abbrev", DEBUG_ABBREV) this.keyword_factory.AddKeyword(".debug_frame", DEBUG_FRAME) this.keyword_factory.AddKeyword(".debug_info", DEBUG_INFO) this.keyword_factory.AddKeyword(".debug_line", DEBUG_LINE) this.keyword_factory.AddKeyword(".debug_loc", DEBUG_LOC) this.keyword_factory.AddKeyword(".debug_ranges", DEBUG_RANGES) this.keyword_factory.AddKeyword(".debug_str", DEBUG_STR) this.keyword_factory.AddKeyword(".dpu_host", DPU_HOST) this.keyword_factory.AddKeyword(".mram", MRAM) this.keyword_factory.AddKeyword(".rodata", RODATA) this.keyword_factory.AddKeyword(".stack_sizes", STACK_SIZES) this.keyword_factory.AddKeyword(".text", TEXT) this.keyword_factory.AddKeyword(".file", FILE) this.keyword_factory.AddKeyword(".section", SECTION) this.keyword_factory.AddKeyword("@progbits", PROGBITS) this.keyword_factory.AddKeyword("@nobits", NOBITS) this.keyword_factory.AddKeyword("@function", FUNCTION) this.keyword_factory.AddKeyword("@object", OBJECT) this.keyword_factory.AddKeyword("true", TRUE) this.keyword_factory.AddKeyword("false", FALSE) this.keyword_factory.AddKeyword("z", Z) this.keyword_factory.AddKeyword("nz", NZ) this.keyword_factory.AddKeyword("e", E) this.keyword_factory.AddKeyword("o", O) this.keyword_factory.AddKeyword("pl", PL) this.keyword_factory.AddKeyword("mi", MI) this.keyword_factory.AddKeyword("ov", OV) this.keyword_factory.AddKeyword("nov", NOV) this.keyword_factory.AddKeyword("c", C) this.keyword_factory.AddKeyword("nc", NC) this.keyword_factory.AddKeyword("sz", SZ) this.keyword_factory.AddKeyword("snz", SNZ) this.keyword_factory.AddKeyword("spl", SPL) this.keyword_factory.AddKeyword("smi", SMI) this.keyword_factory.AddKeyword("so", SO) this.keyword_factory.AddKeyword("se", SE) this.keyword_factory.AddKeyword("nc5", NC5) this.keyword_factory.AddKeyword("nc6", NC6) this.keyword_factory.AddKeyword("nc7", NC7) this.keyword_factory.AddKeyword("nc8", NC8) this.keyword_factory.AddKeyword("nc9", NC9) this.keyword_factory.AddKeyword("nc10", NC10) this.keyword_factory.AddKeyword("nc11", NC11) this.keyword_factory.AddKeyword("nc12", NC12) this.keyword_factory.AddKeyword("nc13", NC13) this.keyword_factory.AddKeyword("nc14", NC14) this.keyword_factory.AddKeyword("max", MAX) this.keyword_factory.AddKeyword("nmax", NMAX) this.keyword_factory.AddKeyword("sh32", SH32) this.keyword_factory.AddKeyword("nsh32", NSH32) this.keyword_factory.AddKeyword("eq", EQ) this.keyword_factory.AddKeyword("neq", NEQ) this.keyword_factory.AddKeyword("ltu", LTU) this.keyword_factory.AddKeyword("leu", LEU) this.keyword_factory.AddKeyword("gtu", GTU) this.keyword_factory.AddKeyword("geu", GEU) this.keyword_factory.AddKeyword("lts", LTS) this.keyword_factory.AddKeyword("les", LES) this.keyword_factory.AddKeyword("gts", GTS) this.keyword_factory.AddKeyword("ges", GES) this.keyword_factory.AddKeyword("xz", XZ) this.keyword_factory.AddKeyword("xnz", XNZ) this.keyword_factory.AddKeyword("xleu", XLEU) this.keyword_factory.AddKeyword("xgtu", XGTU) this.keyword_factory.AddKeyword("xles", XLES) this.keyword_factory.AddKeyword("xgts", XGTS) this.keyword_factory.AddKeyword("small", SMALL) this.keyword_factory.AddKeyword("large", LARGE) this.keyword_factory.AddKeyword("!little", LITTLE) this.keyword_factory.AddKeyword("!big", BIG) this.keyword_factory.AddKeyword("zero", ZERO_REG) this.keyword_factory.AddKeyword("one", ONE) this.keyword_factory.AddKeyword("id", ID) this.keyword_factory.AddKeyword("id2", ID2) this.keyword_factory.AddKeyword("id4", ID4) this.keyword_factory.AddKeyword("id8", ID8) this.keyword_factory.AddKeyword("lneg", LNEG) this.keyword_factory.AddKeyword("mneg", MNEG) this.keyword_factory.AddKeyword(".addrsig", ADDRSIG) this.keyword_factory.AddKeyword(".addrsig_sym", ADDRSIG_SYM) this.keyword_factory.AddKeyword(".ascii", ASCII) this.keyword_factory.AddKeyword(".asciz", ASCIZ) this.keyword_factory.AddKeyword(".byte", BYTE) this.keyword_factory.AddKeyword(".cfi_def_cfa_offset", CFI_DEF_CFA_OFFSET) this.keyword_factory.AddKeyword(".cfi_endproc", CFI_ENDPROC) this.keyword_factory.AddKeyword(".cfi_offset", CFI_OFFSET) this.keyword_factory.AddKeyword(".cfi_sections", CFI_SECTIONS) this.keyword_factory.AddKeyword(".cfi_startproc", CFI_STARTPROC) this.keyword_factory.AddKeyword(".globl", GLOBL) this.keyword_factory.AddKeyword(".loc", LOC) this.keyword_factory.AddKeyword(".long", LONG) this.keyword_factory.AddKeyword(".p2align", P2ALIGN) this.keyword_factory.AddKeyword(".quad", QUAD) this.keyword_factory.AddKeyword(".set", SET) this.keyword_factory.AddKeyword(".short", SHORT) this.keyword_factory.AddKeyword(".size", SIZE) this.keyword_factory.AddKeyword(".type", TYPE) this.keyword_factory.AddKeyword(".weak", WEAK) this.keyword_factory.AddKeyword(".zero", ZERO_DIRECTIVE) this.keyword_factory.AddKeyword("is_stmt", IS_STMT) this.keyword_factory.AddKeyword("prologue_end", PROLOGUE_END) this.keyword_factory.AddKeyword(":", COLON) this.keyword_factory.AddKeyword(",", COMMA) this.keyword_factory.AddKeyword("+", PLUS) this.keyword_factory.AddKeyword("-", MINUS) } func (this *Tokenizer) InitRegexFactory() { this.regex_factory = new(RegexFactory) this.regex_factory.Init() this.regex_factory.AddRegex("^(r)([0-9]*)$", GP_REG) this.regex_factory.AddRegex("^(d)([0-9]*)$", PAIR_REG) this.regex_factory.AddRegex("^([A-Za-z_.])([A-Za-z0-9_]*)$", IDENTIFIER) this.regex_factory.AddRegex("^([0-9]*)$", POSITIVIE_NUMBER) this.regex_factory.AddRegex("^(0x)([0-9]*)$", HEX_NUMBER) this.regex_factory.AddRegex("^(\")(.*)(\")$", STRING) } func (this *Tokenizer) IsTokenizable(word string) bool { return this.keyword_factory.IsTokenizable(word) || this.regex_factory.IsTokenizable(word) } func (this *Tokenizer) Tokenize(word string) *Token { if this.keyword_factory.IsTokenizable(word) { return this.keyword_factory.Tokenize(word) } else if this.regex_factory.IsTokenizable(word) { return this.regex_factory.Tokenize(word) } else { err := errors.New("word is not tokenizable") panic(err) } } ================================================ FILE: golang/uPIMulator/src/linker/linker.go ================================================ package linker import ( "fmt" "os" "path/filepath" "uPIMulator/src/core" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/logic" "uPIMulator/src/linker/parser" "uPIMulator/src/misc" ) type Linker struct { command_line_parser *misc.CommandLineParser root_dirpath string bin_dirpath string benchmark string num_simulation_threads int benchmark_relocatable *kernel.Relocatable sdk_relocatables map[string]*kernel.Relocatable executable *kernel.Executable linker_script *logic.LinkerScript } func (this *Linker) Init(command_line_parser *misc.CommandLineParser) { this.command_line_parser = command_line_parser this.root_dirpath = command_line_parser.StringParameter("root_dirpath") this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") this.num_simulation_threads = int(command_line_parser.IntParameter("num_simulation_threads")) this.InitBenchmarkRelocatable() this.InitSdkRelocatables() this.executable = new(kernel.Executable) this.executable.Init(this.benchmark) this.linker_script = new(logic.LinkerScript) this.linker_script.Init(command_line_parser) } func (this *Linker) InitBenchmarkRelocatable() { benchmark_build_dirpath := filepath.Join(this.root_dirpath, "benchmark", "build") assembly_path := filepath.Join( benchmark_build_dirpath, this.benchmark, "dpu", "CMakeFiles", fmt.Sprintf("%s_device.dir", this.benchmark), "task.c.o", ) this.benchmark_relocatable = new(kernel.Relocatable) this.benchmark_relocatable.Init(this.benchmark) this.benchmark_relocatable.SetPath(assembly_path) } func (this *Linker) InitSdkRelocatables() { this.sdk_relocatables = make(map[string]*kernel.Relocatable, 0) sdk_build_dirpath := filepath.Join(this.root_dirpath, "sdk", "build") sdk_build_dir_entries, sdk_build_dir_read_err := os.ReadDir(sdk_build_dirpath) if sdk_build_dir_read_err != nil { panic(sdk_build_dir_read_err) } for _, sdk_build_dir_entry := range sdk_build_dir_entries { if sdk_build_dir_entry.IsDir() && sdk_build_dir_entry.Name() != "CMakeFiles" { sdk_lib_dirpath := filepath.Join( sdk_build_dirpath, sdk_build_dir_entry.Name(), "CMakeFiles", sdk_build_dir_entry.Name()+".dir", ) sdk_lib_dir_entries, sdk_lib_dir_read_err := os.ReadDir(sdk_lib_dirpath) if sdk_lib_dir_read_err != nil { panic(sdk_lib_dir_read_err) } for _, sdk_lib_dir_entry := range sdk_lib_dir_entries { assembly_path := filepath.Join(sdk_lib_dirpath, sdk_lib_dir_entry.Name()) lib_dir_name := filepath.Base(sdk_lib_dirpath) sdk_relocatable_name := lib_dir_name[:len(lib_dir_name)-4] + "." + sdk_lib_dir_entry.Name()[:len(sdk_lib_dir_entry.Name())-4] sdk_relocatable := new(kernel.Relocatable) sdk_relocatable.Init(sdk_relocatable_name) sdk_relocatable.SetPath(assembly_path) this.sdk_relocatables[sdk_relocatable_name] = sdk_relocatable } } } } func (this *Linker) Link() { this.Lex() this.Parse() this.AnalyzeLiveness() this.MakeExecutable() this.LoadExecutable() this.DumpExecutable() } func (this *Linker) Lex() { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) benchmark_lex_job := new(LexJob) benchmark_lex_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_lex_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_lex_job := new(LexJob) sdk_lex_job.Init(sdk_relocatable) thread_pool.Enque(sdk_lex_job) } thread_pool.Start() } func (this *Linker) Parse() { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) benchmark_parse_job := new(ParseJob) benchmark_parse_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_parse_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_parse_job := new(ParseJob) sdk_parse_job.Init(sdk_relocatable) thread_pool.Enque(sdk_parse_job) } thread_pool.Start() } func (this *Linker) AnalyzeLiveness() { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) benchmark_analyze_liveness_job := new(AnalyzeLivenessJob) benchmark_analyze_liveness_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_analyze_liveness_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_analyze_liveness_job := new(AnalyzeLivenessJob) sdk_analyze_liveness_job.Init(sdk_relocatable) thread_pool.Enque(sdk_analyze_liveness_job) } thread_pool.Start() } func (this *Linker) MakeExecutable() { fmt.Printf("Resolving symbols of %s...\n", this.executable.Name()) this.executable.SetBenchmarkRelocatable(this.benchmark_relocatable) this.ResolveSymbols() executable_path := filepath.Join(this.bin_dirpath, "main.S") fmt.Printf("Dumping the executable to %s...\n", this.executable.Path()) this.executable.SetPath(executable_path) this.executable.DumpAssembly() } func (this *Linker) HasResolved() bool { for unresolved_symbol, _ := range this.executable.Liveness().UnresolvedSymbols() { if !this.linker_script.HasLinkerConstant(unresolved_symbol) { return false } } return true } func (this *Linker) ResolveSymbols() { this.executable.AddSdkRelocatable(this.sdk_relocatables["misc.crt0"]) for !this.HasResolved() { for unresolved_symbol, _ := range this.executable.Liveness().UnresolvedSymbols() { if !this.linker_script.HasLinkerConstant(unresolved_symbol) { for _, sdk_relocatable := range this.sdk_relocatables { if _, found := sdk_relocatable.Liveness().GlobalSymbols()[unresolved_symbol]; found { this.executable.AddSdkRelocatable(sdk_relocatable) } } } } } } func (this *Linker) LoadExecutable() { fmt.Println("Re-lexing executable") lexer_ := new(lexer.Lexer) lexer_.Init() token_stream := lexer_.Lex(this.executable.Path()) this.executable.SetTokenStream(token_stream) fmt.Println("Re-parsing executable...") parser_ := new(parser.Parser) parser_.Init() ast := parser_.Parse(token_stream) this.executable.SetAst(ast) fmt.Println("Assigning labels...") label_assigner := new(logic.LabelAssigner) label_assigner.Init() label_assigner.Assign(this.executable) fmt.Println("Assigning addresses..") this.linker_script.Assign(this.executable) fmt.Println("Setting alias labels...") set_assigner := new(logic.SetAssigner) set_assigner.Init() set_assigner.Assign(this.executable) fmt.Println("Assigning instructions...") instruction_assigner := new(logic.InstructionAssigner) instruction_assigner.Init(this.linker_script) instruction_assigner.Assign(this.executable) } func (this *Linker) DumpExecutable() { this.linker_script.DumpValues(filepath.Join(this.bin_dirpath, "values.txt")) this.executable.DumpAddresses(filepath.Join(this.bin_dirpath, "addresses.txt")) this.executable.DumpAtomic(filepath.Join(this.bin_dirpath, "atomic.bin")) this.executable.DumpIram(filepath.Join(this.bin_dirpath, "iram.bin")) this.executable.DumpWram(filepath.Join(this.bin_dirpath, "wram.bin")) this.executable.DumpMram(filepath.Join(this.bin_dirpath, "mram.bin")) } ================================================ FILE: golang/uPIMulator/src/linker/logic/instruction_assigner.go ================================================ package logic import ( "errors" "strconv" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/kernel/directive" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/linker/kernel/instruction/cc" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" "uPIMulator/src/misc" ) type InstructionAssigner struct { executable *kernel.Executable walker *parser.Walker linker_script *LinkerScript } func (this *InstructionAssigner) Init(linker_script *LinkerScript) { this.linker_script = linker_script this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback(stmt.ASCII, this.WalkAsciiStmt) this.walker.RegisterStmtCallback(stmt.ASCIZ, this.WalkAscizStmt) this.walker.RegisterStmtCallback(stmt.BYTE, this.WalkByteStmt) this.walker.RegisterStmtCallback(stmt.LONG_PROGRAM_COUNTER, this.WalkLongProgramCounterStmt) this.walker.RegisterStmtCallback(stmt.LONG_SECTION_NAME, this.WalkLongSectionNameStmt) this.walker.RegisterStmtCallback(stmt.QUAD, this.WalkQuadStmt) this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.SHORT, this.WalkShortStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) this.walker.RegisterStmtCallback(stmt.ZERO_DOUBLE_NUMBER, this.WalkZeroDoubleNumberStmt) this.walker.RegisterStmtCallback(stmt.ZERO_SINGLE_NUMBER, this.WalkZeroSingleNumberStmt) this.walker.RegisterStmtCallback(stmt.CI, this.WalkCiStmt) this.walker.RegisterStmtCallback(stmt.DMA_RRI, this.WalkDmaRriStmt) this.walker.RegisterStmtCallback(stmt.DRDICI, this.WalkDrdiciStmt) this.walker.RegisterStmtCallback(stmt.EDRI, this.WalkEdriStmt) this.walker.RegisterStmtCallback(stmt.ERID, this.WalkEridStmt) this.walker.RegisterStmtCallback(stmt.ERII, this.WalkEriiStmt) this.walker.RegisterStmtCallback(stmt.ERIR, this.WalkErirStmt) this.walker.RegisterStmtCallback(stmt.ERRI, this.WalkErriStmt) this.walker.RegisterStmtCallback(stmt.I, this.WalkIStmt) this.walker.RegisterStmtCallback(stmt.NOP, this.WalkNopStmt) this.walker.RegisterStmtCallback(stmt.RCI, this.WalkRciStmt) this.walker.RegisterStmtCallback(stmt.RICI, this.WalkRiciStmt) this.walker.RegisterStmtCallback(stmt.RIRCI, this.WalkRirciStmt) this.walker.RegisterStmtCallback(stmt.RIRC, this.WalkRircStmt) this.walker.RegisterStmtCallback(stmt.RIR, this.WalkRirStmt) this.walker.RegisterStmtCallback(stmt.RRCI, this.WalkRrciStmt) this.walker.RegisterStmtCallback(stmt.RRC, this.WalkRrcStmt) this.walker.RegisterStmtCallback(stmt.RRICI, this.WalkRriciStmt) this.walker.RegisterStmtCallback(stmt.RRIC, this.WalkRricStmt) this.walker.RegisterStmtCallback(stmt.RRI, this.WalkRriStmt) this.walker.RegisterStmtCallback(stmt.RRRCI, this.WalkRrrciStmt) this.walker.RegisterStmtCallback(stmt.RRRC, this.WalkRrrcStmt) this.walker.RegisterStmtCallback(stmt.RRRICI, this.WalkRrriciStmt) this.walker.RegisterStmtCallback(stmt.RRRI, this.WalkRrriStmt) this.walker.RegisterStmtCallback(stmt.RRR, this.WalkRrrStmt) this.walker.RegisterStmtCallback(stmt.RR, this.WalkRrStmt) this.walker.RegisterStmtCallback(stmt.R, this.WalkRStmt) this.walker.RegisterStmtCallback(stmt.S_ERRI, this.WalkSErriStmt) this.walker.RegisterStmtCallback(stmt.S_RCI, this.WalkSRciStmt) this.walker.RegisterStmtCallback(stmt.S_RIRCI, this.WalkSRirciStmt) this.walker.RegisterStmtCallback(stmt.S_RIRC, this.WalkSRircStmt) this.walker.RegisterStmtCallback(stmt.S_RRCI, this.WalkSRrciStmt) this.walker.RegisterStmtCallback(stmt.S_RRC, this.WalkSRrcStmt) this.walker.RegisterStmtCallback(stmt.S_RRICI, this.WalkSRriciStmt) this.walker.RegisterStmtCallback(stmt.S_RRIC, this.WalkSRricStmt) this.walker.RegisterStmtCallback(stmt.S_RRI, this.WalkSRriStmt) this.walker.RegisterStmtCallback(stmt.S_RRRCI, this.WalkSRrrciStmt) this.walker.RegisterStmtCallback(stmt.S_RRRC, this.WalkSRrrcStmt) this.walker.RegisterStmtCallback(stmt.S_RRRICI, this.WalkSRrriciStmt) this.walker.RegisterStmtCallback(stmt.S_RRRI, this.WalkSRrriStmt) this.walker.RegisterStmtCallback(stmt.S_RRR, this.WalkSRrrStmt) this.walker.RegisterStmtCallback(stmt.S_RR, this.WalkSRrStmt) this.walker.RegisterStmtCallback(stmt.S_R, this.WalkSRStmt) this.walker.RegisterStmtCallback(stmt.BKP, this.WalkBkpStmt) this.walker.RegisterStmtCallback(stmt.BOOT_RI, this.WalkBootRiStmt) this.walker.RegisterStmtCallback(stmt.CALL_RI, this.WalkCallRiStmt) this.walker.RegisterStmtCallback(stmt.CALL_RR, this.WalkCallRrStmt) this.walker.RegisterStmtCallback(stmt.DIV_STEP_DRDI, this.WalkDivStepDrdiStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RII, this.WalkJeqRiiStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RRI, this.WalkJeqRriStmt) this.walker.RegisterStmtCallback(stmt.JNZ_RI, this.WalkJnzRiStmt) this.walker.RegisterStmtCallback(stmt.JUMP_I, this.WalkJumpIStmt) this.walker.RegisterStmtCallback(stmt.JUMP_R, this.WalkJumpRStmt) this.walker.RegisterStmtCallback(stmt.LBS_RRI, this.WalkLbsRriStmt) this.walker.RegisterStmtCallback(stmt.LBS_S_RRI, this.WalkLbsSRriStmt) this.walker.RegisterStmtCallback(stmt.LD_DRI, this.WalkLdDriStmt) this.walker.RegisterStmtCallback(stmt.MOVD_DD, this.WalkMovdDdStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RICI, this.WalkMoveRiciStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RI, this.WalkMoveRiStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RICI, this.WalkMoveSRiciStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RI, this.WalkMoveSRiStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RII, this.WalkSbIdRiiStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RI, this.WalkSbIdRiStmt) this.walker.RegisterStmtCallback(stmt.SB_RIR, this.WalkSbRirStmt) this.walker.RegisterStmtCallback(stmt.SD_RID, this.WalkSdRidStmt) this.walker.RegisterStmtCallback(stmt.STOP, this.WalkStopStmt) this.walker.RegisterStmtCallback(stmt.TIME_CFG_R, this.WalkTimeCfgRStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *InstructionAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *InstructionAssigner) WalkAsciiStmt(stmt_ *stmt.Stmt) { ascii_stmt := stmt_.AsciiStmt() token := ascii_stmt.Token() attribute := token.Attribute() characters := attribute[1 : len(attribute)-1] // TODO(bongjoon.hyun@gmail.com): decode octal code ascii_directive := new(directive.AsciiDirective) ascii_directive.Init(characters) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(ascii_directive) } func (this *InstructionAssigner) WalkAscizStmt(stmt_ *stmt.Stmt) { asciz_stmt := stmt_.AscizStmt() token := asciz_stmt.Token() attribute := token.Attribute() characters := attribute[1 : len(attribute)-1] asciz_directive := new(directive.AscizDirective) asciz_directive.Init(characters) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(asciz_directive) } func (this *InstructionAssigner) WalkByteStmt(stmt_ *stmt.Stmt) { byte_stmt := stmt_.ByteStmt() value := this.EvaluateProgramCounter(byte_stmt.Expr()) byte_directive := new(directive.ByteDirective) byte_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(byte_directive) } func (this *InstructionAssigner) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { long_program_counter_stmt := stmt_.LongProgramCounterStmt() value := this.EvaluateProgramCounter(long_program_counter_stmt.Expr()) long_directive := new(directive.LongDirective) long_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(long_directive) } func (this *InstructionAssigner) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { long_section_name_stmt := stmt_.LongSectionNameStmt() value := this.EvaluateSectionName(long_section_name_stmt.Expr()) long_directive := new(directive.LongDirective) long_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(long_directive) } func (this *InstructionAssigner) WalkQuadStmt(stmt_ *stmt.Stmt) { quad_stmt := stmt_.QuadStmt() value := this.EvaluateProgramCounter(quad_stmt.Expr()) quad_directive := new(directive.QuadDirective) quad_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(quad_directive) } func (this *InstructionAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkShortStmt(stmt_ *stmt.Stmt) { short_stmt := stmt_.ShortStmt() value := this.EvaluateProgramCounter(short_stmt.Expr()) short_directive := new(directive.ShortDirective) short_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(short_directive) } func (this *InstructionAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() size := this.EvaluateProgramCounter(zero_double_number_stmt.Expr1()) value := this.EvaluateProgramCounter(zero_double_number_stmt.Expr2()) zero_directive := new(directive.ZeroDirective) zero_directive.Init(size, value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(zero_directive) } func (this *InstructionAssigner) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() size := this.EvaluateProgramCounter(zero_single_number_stmt.Expr()) zero_directive := new(directive.ZeroDirective) zero_directive.Init(size, 0) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(zero_directive) } func (this *InstructionAssigner) WalkCiStmt(stmt_ *stmt.Stmt) { ci_stmt := stmt_.CiStmt() op_code := this.ConvertCiOpCode(ci_stmt.OpCode()) condition := this.ConvertCondition(ci_stmt.Condition()) pc := this.EvaluateProgramCounter(ci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitCi(op_code, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDdciStmt(stmt_ *stmt.Stmt) { ddci_stmt := stmt_.DdciStmt() op_code := this.ConvertDdciOpCode(ddci_stmt.OpCode()) dc := this.ConvertPairReg(ddci_stmt.Dc()) db := this.ConvertPairReg(ddci_stmt.Db()) condition := this.ConvertCondition(ddci_stmt.Condition()) pc := this.EvaluateProgramCounter(ddci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitDdci(op_code, dc, db, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDmaRriStmt(stmt_ *stmt.Stmt) { dma_rri_stmt := stmt_.DmaRriStmt() op_code := this.ConvertDmaRriOpCode(dma_rri_stmt.OpCode()) ra := this.ConvertSrcReg(dma_rri_stmt.Ra()) rb := this.ConvertSrcReg(dma_rri_stmt.Rb()) imm := this.EvaluateProgramCounter(dma_rri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitDmaRri(op_code, ra, rb, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDrdiciStmt(stmt_ *stmt.Stmt) { drdici_stmt := stmt_.DrdiciStmt() op_code := this.ConvertDrdiciOpCode(drdici_stmt.OpCode()) dc := this.ConvertPairReg(drdici_stmt.Dc()) ra := this.ConvertSrcReg(drdici_stmt.Ra()) db := this.ConvertPairReg(drdici_stmt.Db()) imm := this.EvaluateProgramCounter(drdici_stmt.Imm()) condition := this.ConvertCondition(drdici_stmt.Condition()) pc := this.EvaluateProgramCounter(drdici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitDrdici(op_code, dc, ra, db, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEdriStmt(stmt_ *stmt.Stmt) { edri_stmt := stmt_.EdriStmt() op_code := this.ConvertLoadOpCode(edri_stmt.OpCode()) endian := this.ConvertEndian(edri_stmt.Endian()) dc := this.ConvertPairReg(edri_stmt.Dc()) ra := this.ConvertSrcReg(edri_stmt.Ra()) off := this.EvaluateProgramCounter(edri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitEdri(op_code, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEridStmt(stmt_ *stmt.Stmt) { erid_stmt := stmt_.EridStmt() op_code := this.ConvertStoreOpCode(erid_stmt.OpCode()) endian := this.ConvertEndian(erid_stmt.Endian()) ra := this.ConvertSrcReg(erid_stmt.Ra()) off := this.EvaluateProgramCounter(erid_stmt.Off()) db := this.ConvertPairReg(erid_stmt.Db()) instruction_ := new(instruction.Instruction) instruction_.InitErid(op_code, endian, ra, off, db) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEriiStmt(stmt_ *stmt.Stmt) { erii_stmt := stmt_.EriiStmt() op_code := this.ConvertStoreOpCode(erii_stmt.OpCode()) endian := this.ConvertEndian(erii_stmt.Endian()) ra := this.ConvertSrcReg(erii_stmt.Ra()) off := this.EvaluateProgramCounter(erii_stmt.Off()) imm := this.EvaluateProgramCounter(erii_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkErirStmt(stmt_ *stmt.Stmt) { erir_stmt := stmt_.ErirStmt() op_code := this.ConvertStoreOpCode(erir_stmt.OpCode()) endian := this.ConvertEndian(erir_stmt.Endian()) ra := this.ConvertSrcReg(erir_stmt.Ra()) off := this.EvaluateProgramCounter(erir_stmt.Off()) rb := this.ConvertSrcReg(erir_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitErir(op_code, endian, ra, off, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkErriStmt(stmt_ *stmt.Stmt) { erri_stmt := stmt_.ErriStmt() op_code := this.ConvertLoadOpCode(erri_stmt.OpCode()) endian := this.ConvertEndian(erri_stmt.Endian()) rc := this.ConvertGpReg(erri_stmt.Rc()) ra := this.ConvertSrcReg(erri_stmt.Ra()) off := this.EvaluateProgramCounter(erri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitErri(op_code, endian, rc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkIStmt(stmt_ *stmt.Stmt) { i_stmt := stmt_.IStmt() op_code := this.ConvertIOpCode(i_stmt.OpCode()) imm := this.EvaluateProgramCounter(i_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitI(op_code, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkNopStmt(stmt_ *stmt.Stmt) { nop_stmt := stmt_.NopStmt() op_code := this.ConvertROpCode(nop_stmt.OpCode()) instruction_ := new(instruction.Instruction) instruction_.InitZ(op_code) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRciStmt(stmt_ *stmt.Stmt) { rci_stmt := stmt_.RciStmt() is_zero_reg := this.IsZeroReg(rci_stmt.Rc()) op_code := this.ConvertROpCode(rci_stmt.OpCode()) condition := this.ConvertCondition(rci_stmt.Condition()) pc := this.EvaluateProgramCounter(rci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rci_stmt.Rc()) instruction_.InitRci(op_code, rc, condition, pc) } else { instruction_.InitZci(op_code, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRiciStmt(stmt_ *stmt.Stmt) { rici_stmt := stmt_.RiciStmt() op_code := this.ConvertRiciOpCode(rici_stmt.OpCode()) ra := this.ConvertSrcReg(rici_stmt.Ra()) imm := this.EvaluateProgramCounter(rici_stmt.Imm()) condition := this.ConvertCondition(rici_stmt.Condition()) pc := this.EvaluateProgramCounter(rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitRici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRirciStmt(stmt_ *stmt.Stmt) { rirci_stmt := stmt_.RirciStmt() is_zero_reg := this.IsZeroReg(rirci_stmt.Rc()) op_code := this.ConvertRriOpCode(rirci_stmt.OpCode()) imm := this.EvaluateProgramCounter(rirci_stmt.Imm()) ra := this.ConvertSrcReg(rirci_stmt.Ra()) condition := this.ConvertCondition(rirci_stmt.Condition()) pc := this.EvaluateProgramCounter(rirci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rirci_stmt.Rc()) instruction_.InitRirci(op_code, rc, imm, ra, condition, pc) } else { instruction_.InitZirci(op_code, imm, ra, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRircStmt(stmt_ *stmt.Stmt) { rirc_stmt := stmt_.RircStmt() is_zero_reg := this.IsZeroReg(rirc_stmt.Rc()) op_code := this.ConvertRriOpCode(rirc_stmt.OpCode()) imm := this.EvaluateProgramCounter(rirc_stmt.Imm()) ra := this.ConvertSrcReg(rirc_stmt.Ra()) condition := this.ConvertCondition(rirc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rirc_stmt.Rc()) instruction_.InitRirc(op_code, rc, imm, ra, condition) } else { instruction_.InitZirc(op_code, imm, ra, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRirStmt(stmt_ *stmt.Stmt) { rir_stmt := stmt_.RirStmt() is_zero_reg := this.IsZeroReg(rir_stmt.Rc()) op_code := this.ConvertRriOpCode(rir_stmt.OpCode()) imm := this.EvaluateProgramCounter(rir_stmt.Imm()) ra := this.ConvertSrcReg(rir_stmt.Ra()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rir_stmt.Rc()) instruction_.InitRir(op_code, rc, imm, ra) } else { instruction_.InitZir(op_code, imm, ra) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrciStmt(stmt_ *stmt.Stmt) { rrci_stmt := stmt_.RrciStmt() op_code := this.ConvertRrOpCode(rrci_stmt.OpCode()) ra := this.ConvertSrcReg(rrci_stmt.Ra()) condition := this.ConvertCondition(rrci_stmt.Condition()) pc := this.EvaluateProgramCounter(rrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(0) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else if op_code == instruction.SUB { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(0) instruction_.InitRirci(op_code, rc, imm, ra, condition, pc) } else if op_code == instruction.XOR { is_zero_reg := this.IsZeroReg(rrci_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(-1) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else { imm := int64(-1) instruction_.InitZrici(op_code, ra, imm, condition, pc) } } else { is_zero_reg := this.IsZeroReg(rrci_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rrci_stmt.Rc()) instruction_.InitRrci(op_code, rc, ra, condition, pc) } else { instruction_.InitZrci(op_code, ra, condition, pc) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrcStmt(stmt_ *stmt.Stmt) { rrc_stmt := stmt_.RrcStmt() is_zero_reg := this.IsZeroReg(rrc_stmt.Rc()) op_code := this.ConvertRrOpCode(rrc_stmt.OpCode()) ra := this.ConvertSrcReg(rrc_stmt.Ra()) condition := this.ConvertCondition(rrc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrc_stmt.Rc()) instruction_.InitRrc(op_code, rc, ra, condition) } else { instruction_.InitZrc(op_code, ra, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRriciStmt(stmt_ *stmt.Stmt) { rrici_stmt := stmt_.RriciStmt() is_zero_reg := this.IsZeroReg(rrici_stmt.Rc()) op_code := this.ConvertRriOpCode(rrici_stmt.OpCode()) ra := this.ConvertSrcReg(rrici_stmt.Ra()) imm := this.EvaluateProgramCounter(rrici_stmt.Imm()) condition := this.ConvertCondition(rrici_stmt.Condition()) pc := this.EvaluateProgramCounter(rrici_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrici_stmt.Rc()) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else { instruction_.InitZrici(op_code, ra, imm, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRricStmt(stmt_ *stmt.Stmt) { rric_stmt := stmt_.RricStmt() is_zero_reg := this.IsZeroReg(rric_stmt.Rc()) op_code := this.ConvertRriOpCode(rric_stmt.OpCode()) ra := this.ConvertSrcReg(rric_stmt.Ra()) imm := this.EvaluateProgramCounter(rric_stmt.Imm()) condition := this.ConvertCondition(rric_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rric_stmt.Rc()) if condition != cc.FALSE { instruction_.InitRric(op_code, rc, ra, imm, condition) } else { instruction_.InitRrif(op_code, rc, ra, imm, condition) } } else { if condition != cc.FALSE { instruction_.InitZric(op_code, ra, imm, condition) } else { instruction_.InitZrif(op_code, ra, imm, condition) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRriStmt(stmt_ *stmt.Stmt) { rri_stmt := stmt_.RriStmt() is_zero_reg := this.IsZeroReg(rri_stmt.Rc()) op_code := this.ConvertRriOpCode(rri_stmt.OpCode()) ra := this.ConvertSrcReg(rri_stmt.Ra()) imm := this.EvaluateProgramCounter(rri_stmt.Imm()) instruction_ := new(instruction.Instruction) if op_code == instruction.ANDN || op_code == instruction.NAND || op_code == instruction.NOR || op_code == instruction.NXOR || op_code == instruction.ORN { rc := this.ConvertGpReg(rri_stmt.Rc()) condition := cc.FALSE instruction_.InitRrif(op_code, rc, ra, imm, condition) } else if !is_zero_reg { rc := this.ConvertGpReg(rri_stmt.Rc()) instruction_.InitRri(op_code, rc, ra, imm) } else { instruction_.InitZri(op_code, ra, imm) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrciStmt(stmt_ *stmt.Stmt) { rrrci_stmt := stmt_.RrrciStmt() is_zero_reg := this.IsZeroReg(rrrci_stmt.Rc()) op_code := this.ConvertRriOpCode(rrrci_stmt.OpCode()) ra := this.ConvertSrcReg(rrrci_stmt.Ra()) rb := this.ConvertSrcReg(rrrci_stmt.Rb()) condition := this.ConvertCondition(rrrci_stmt.Condition()) pc := this.EvaluateProgramCounter(rrrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrci_stmt.Rc()) instruction_.InitRrrci(op_code, rc, ra, rb, condition, pc) } else { instruction_.InitZrrci(op_code, ra, rb, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrcStmt(stmt_ *stmt.Stmt) { rrrc_stmt := stmt_.RrrcStmt() is_zero_reg := this.IsZeroReg(rrrc_stmt.Rc()) op_code := this.ConvertRriOpCode(rrrc_stmt.OpCode()) ra := this.ConvertSrcReg(rrrc_stmt.Ra()) rb := this.ConvertSrcReg(rrrc_stmt.Rb()) condition := this.ConvertCondition(rrrc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrc_stmt.Rc()) instruction_.InitRrrc(op_code, rc, ra, rb, condition) } else { instruction_.InitZrrc(op_code, ra, rb, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrriciStmt(stmt_ *stmt.Stmt) { rrrici_stmt := stmt_.RrriciStmt() is_zero_reg := this.IsZeroReg(rrrici_stmt.Rc()) op_code := this.ConvertRrriOpCode(rrrici_stmt.OpCode()) ra := this.ConvertSrcReg(rrrici_stmt.Ra()) rb := this.ConvertSrcReg(rrrici_stmt.Rb()) imm := this.EvaluateProgramCounter(rrrici_stmt.Imm()) condition := this.ConvertCondition(rrrici_stmt.Condition()) pc := this.EvaluateProgramCounter(rrrici_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrici_stmt.Rc()) instruction_.InitRrrici(op_code, rc, ra, rb, imm, condition, pc) } else { instruction_.InitZrrici(op_code, ra, rb, imm, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrriStmt(stmt_ *stmt.Stmt) { rrri_stmt := stmt_.RrriStmt() is_zero_reg := this.IsZeroReg(rrri_stmt.Rc()) op_code := this.ConvertRrriOpCode(rrri_stmt.OpCode()) ra := this.ConvertSrcReg(rrri_stmt.Ra()) rb := this.ConvertSrcReg(rrri_stmt.Rb()) imm := this.EvaluateProgramCounter(rrri_stmt.Imm()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrri_stmt.Rc()) instruction_.InitRrri(op_code, rc, ra, rb, imm) } else { instruction_.InitZrri(op_code, ra, rb, imm) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrStmt(stmt_ *stmt.Stmt) { rrr_stmt := stmt_.RrrStmt() is_zero_reg := this.IsZeroReg(rrr_stmt.Rc()) op_code := this.ConvertRriOpCode(rrr_stmt.OpCode()) ra := this.ConvertSrcReg(rrr_stmt.Ra()) rb := this.ConvertSrcReg(rrr_stmt.Rb()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrr_stmt.Rc()) instruction_.InitRrr(op_code, rc, ra, rb) } else { instruction_.InitZrr(op_code, ra, rb) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrStmt(stmt_ *stmt.Stmt) { rr_stmt := stmt_.RrStmt() op_code := this.ConvertRrOpCode(rr_stmt.OpCode()) ra := this.ConvertSrcReg(rr_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(0) condition := cc.FALSE instruction_.InitRrif(op_code, rc, ra, imm, condition) } else if op_code == instruction.SUB { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(0) instruction_.InitRir(op_code, rc, imm, ra) } else if op_code == instruction.XOR { is_zero_reg := this.IsZeroReg(rr_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(-1) instruction_.InitRri(op_code, rc, ra, imm) } else { imm := int64(-1) instruction_.InitZri(op_code, ra, imm) } } else { is_zero_reg := this.IsZeroReg(rr_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rr_stmt.Rc()) instruction_.InitRr(op_code, rc, ra) } else { instruction_.InitZr(op_code, ra) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRStmt(stmt_ *stmt.Stmt) { r_stmt := stmt_.RStmt() is_zero_reg := this.IsZeroReg(r_stmt.Rc()) op_code := this.ConvertROpCode(r_stmt.OpCode()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(r_stmt.Rc()) instruction_.InitR(op_code, rc) } else { instruction_.InitZ(op_code) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSErriStmt(stmt_ *stmt.Stmt) { s_erri_stmt := stmt_.SErriStmt() op_code := this.ConvertLoadOpCode(s_erri_stmt.OpCode()) suffix := this.ConvertSuffix(s_erri_stmt.Suffix(), instruction.ERRI) endian := this.ConvertEndian(s_erri_stmt.Endian()) dc := this.ConvertPairReg(s_erri_stmt.Dc()) ra := this.ConvertSrcReg(s_erri_stmt.Ra()) off := this.EvaluateProgramCounter(s_erri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitSErri(op_code, suffix, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRciStmt(stmt_ *stmt.Stmt) { s_rci_stmt := stmt_.SRciStmt() op_code := this.ConvertROpCode(s_rci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rci_stmt.Suffix(), instruction.RCI) dc := this.ConvertPairReg(s_rci_stmt.Dc()) condition := this.ConvertCondition(s_rci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRci(op_code, suffix, dc, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRirciStmt(stmt_ *stmt.Stmt) { s_rirci_stmt := stmt_.SRirciStmt() op_code := this.ConvertRriOpCode(s_rirci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rirci_stmt.Suffix(), instruction.RIRCI) dc := this.ConvertPairReg(s_rirci_stmt.Dc()) imm := this.EvaluateProgramCounter(s_rirci_stmt.Imm()) ra := this.ConvertSrcReg(s_rirci_stmt.Ra()) condition := this.ConvertCondition(s_rirci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rirci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRirci(op_code, suffix, dc, imm, ra, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRircStmt(stmt_ *stmt.Stmt) { s_rirc_stmt := stmt_.SRircStmt() op_code := this.ConvertRriOpCode(s_rirc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rirc_stmt.Suffix(), instruction.RIRC) dc := this.ConvertPairReg(s_rirc_stmt.Dc()) imm := this.EvaluateProgramCounter(s_rirc_stmt.Imm()) ra := this.ConvertSrcReg(s_rirc_stmt.Ra()) condition := this.ConvertCondition(s_rirc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRirc(op_code, suffix, dc, imm, ra, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrciStmt(stmt_ *stmt.Stmt) { s_rrci_stmt := stmt_.SRrciStmt() op_code := this.ConvertRrOpCode(s_rrci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrci_stmt.Suffix(), instruction.RRCI) dc := this.ConvertPairReg(s_rrci_stmt.Dc()) ra := this.ConvertSrcReg(s_rrci_stmt.Ra()) condition := this.ConvertCondition(s_rrci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { if suffix == instruction.S_RRCI { suffix = instruction.S_RRICI imm := int64(0) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) } else { suffix = instruction.U_RRICI imm := int64(0) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) } } else { instruction_.InitSRrci(op_code, suffix, dc, ra, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrcStmt(stmt_ *stmt.Stmt) { s_rrc_stmt := stmt_.SRrcStmt() op_code := this.ConvertRriOpCode(s_rrc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrc_stmt.Suffix(), instruction.RRC) dc := this.ConvertPairReg(s_rrc_stmt.Dc()) ra := this.ConvertSrcReg(s_rrc_stmt.Ra()) condition := this.ConvertCondition(s_rrc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRrc(op_code, suffix, dc, ra, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRriciStmt(stmt_ *stmt.Stmt) { s_rrici_stmt := stmt_.SRriciStmt() op_code := this.ConvertRriOpCode(s_rrici_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrici_stmt.Suffix(), instruction.RRICI) dc := this.ConvertPairReg(s_rrici_stmt.Dc()) ra := this.ConvertSrcReg(s_rrici_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rrici_stmt.Imm()) condition := this.ConvertCondition(s_rrici_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRricStmt(stmt_ *stmt.Stmt) { s_rric_stmt := stmt_.SRricStmt() op_code := this.ConvertRriOpCode(s_rric_stmt.OpCode()) suffix := this.ConvertSuffix(s_rric_stmt.Suffix(), instruction.RRIC) dc := this.ConvertPairReg(s_rric_stmt.Dc()) ra := this.ConvertSrcReg(s_rric_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rric_stmt.Imm()) condition := this.ConvertCondition(s_rric_stmt.Condition()) instruction_ := new(instruction.Instruction) if condition != cc.FALSE { instruction_.InitSRric(op_code, suffix, dc, ra, imm, condition) } else { instruction_.InitSRrif(op_code, suffix, dc, ra, imm, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRriStmt(stmt_ *stmt.Stmt) { s_rri_stmt := stmt_.SRriStmt() op_code := this.ConvertRriOpCode(s_rri_stmt.OpCode()) suffix := this.ConvertSuffix(s_rri_stmt.Suffix(), instruction.RRI) dc := this.ConvertPairReg(s_rri_stmt.Dc()) ra := this.ConvertSrcReg(s_rri_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRri(op_code, suffix, dc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrciStmt(stmt_ *stmt.Stmt) { s_rrrci_stmt := stmt_.SRrrciStmt() op_code := this.ConvertRriOpCode(s_rrrci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrci_stmt.Suffix(), instruction.RRRCI) dc := this.ConvertPairReg(s_rrrci_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrci_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrci_stmt.Rb()) condition := this.ConvertCondition(s_rrrci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrrci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrci(op_code, suffix, dc, ra, rb, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrcStmt(stmt_ *stmt.Stmt) { s_rrrc_stmt := stmt_.SRrrcStmt() op_code := this.ConvertRriOpCode(s_rrrc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrc_stmt.Suffix(), instruction.RRRC) dc := this.ConvertPairReg(s_rrrc_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrc_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrc_stmt.Rb()) condition := this.ConvertCondition(s_rrrc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrc(op_code, suffix, dc, ra, rb, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrriciStmt(stmt_ *stmt.Stmt) { s_rrrici_stmt := stmt_.SRrriciStmt() op_code := this.ConvertRriOpCode(s_rrrici_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrici_stmt.Suffix(), instruction.RRRICI) dc := this.ConvertPairReg(s_rrrici_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrici_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrici_stmt.Rb()) imm := this.EvaluateProgramCounter(s_rrrici_stmt.Imm()) condition := this.ConvertCondition(s_rrrici_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrrici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrici(op_code, suffix, dc, ra, rb, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrriStmt(stmt_ *stmt.Stmt) { s_rrri_stmt := stmt_.SRrriStmt() op_code := this.ConvertRriOpCode(s_rrri_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrri_stmt.Suffix(), instruction.RRRI) dc := this.ConvertPairReg(s_rrri_stmt.Dc()) ra := this.ConvertSrcReg(s_rrri_stmt.Ra()) rb := this.ConvertSrcReg(s_rrri_stmt.Rb()) imm := this.EvaluateProgramCounter(s_rrri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRrri(op_code, suffix, dc, ra, rb, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrStmt(stmt_ *stmt.Stmt) { s_rrr_stmt := stmt_.SRrrStmt() op_code := this.ConvertRriOpCode(s_rrr_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrr_stmt.Suffix(), instruction.RRR) dc := this.ConvertPairReg(s_rrr_stmt.Dc()) ra := this.ConvertSrcReg(s_rrr_stmt.Ra()) rb := this.ConvertSrcReg(s_rrr_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitSRrr(op_code, suffix, dc, ra, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrStmt(stmt_ *stmt.Stmt) { s_rr_stmt := stmt_.SRrStmt() op_code := this.ConvertRrOpCode(s_rr_stmt.OpCode()) suffix := this.ConvertSuffix(s_rr_stmt.Suffix(), instruction.RR) dc := this.ConvertPairReg(s_rr_stmt.Dc()) ra := this.ConvertSrcReg(s_rr_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { if suffix == instruction.S_RR { imm := int64(0) condition := cc.FALSE instruction_.InitSRrif(op_code, instruction.S_RRIF, dc, ra, imm, condition) } else if suffix == instruction.U_RR { imm := int64(0) condition := cc.FALSE instruction_.InitSRrif(op_code, instruction.U_RRIF, dc, ra, imm, condition) } else { err := errors.New("suffix is not valid") panic(err) } } else { instruction_.InitSRr(op_code, suffix, dc, ra) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRStmt(stmt_ *stmt.Stmt) { s_r_stmt := stmt_.SRStmt() op_code := this.ConvertRriOpCode(s_r_stmt.OpCode()) suffix := this.ConvertSuffix(s_r_stmt.Suffix(), instruction.R) dc := this.ConvertPairReg(s_r_stmt.Dc()) instruction_ := new(instruction.Instruction) instruction_.InitSR(op_code, suffix, dc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkBkpStmt(stmt_ *stmt.Stmt) { op_code := instruction.FAULT imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitI(op_code, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkBootRiStmt(stmt_ *stmt.Stmt) { boot_ri_stmt := stmt_.BootRiStmt() op_code := this.ConvertRiciOpCode(boot_ri_stmt.OpCode()) ra := this.ConvertSrcReg(boot_ri_stmt.Ra()) imm := this.EvaluateProgramCounter(boot_ri_stmt.Imm()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitRici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkCallRiStmt(stmt_ *stmt.Stmt) { call_ri_stmt := stmt_.CallRiStmt() op_code := instruction.CALL rc := this.ConvertGpReg(call_ri_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(call_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkCallRrStmt(stmt_ *stmt.Stmt) { call_rr_stmt := stmt_.CallRrStmt() op_code := instruction.CALL rc := this.ConvertGpReg(call_rr_stmt.Rc()) ra := this.ConvertSrcReg(call_rr_stmt.Ra()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDivStepDrdiStmt(stmt_ *stmt.Stmt) { div_step_drdi_stmt := stmt_.DivStepDrdiStmt() op_code := this.ConvertDrdiciOpCode(div_step_drdi_stmt.OpCode()) dc := this.ConvertPairReg(div_step_drdi_stmt.Dc()) ra := this.ConvertSrcReg(div_step_drdi_stmt.Ra()) db := this.ConvertPairReg(div_step_drdi_stmt.Db()) imm := this.EvaluateProgramCounter(div_step_drdi_stmt.Imm()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitDrdici(op_code, dc, ra, db, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJeqRiiStmt(stmt_ *stmt.Stmt) { jeq_rii_stmt := stmt_.JeqRiiStmt() op_code := this.ConvertJumpOpCode(jeq_rii_stmt.OpCode()) ra := this.ConvertSrcReg(jeq_rii_stmt.Ra()) imm := this.EvaluateProgramCounter(jeq_rii_stmt.Imm()) condition := this.ConvertJumpCondition(jeq_rii_stmt.OpCode()) pc := this.EvaluateProgramCounter(jeq_rii_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZrici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJeqRriStmt(stmt_ *stmt.Stmt) { jeq_rri_stmt := stmt_.JeqRriStmt() op_code := this.ConvertJumpOpCode(jeq_rri_stmt.OpCode()) ra := this.ConvertSrcReg(jeq_rri_stmt.Ra()) rb := this.ConvertSrcReg(jeq_rri_stmt.Rb()) condition := this.ConvertJumpCondition(jeq_rri_stmt.OpCode()) pc := this.EvaluateProgramCounter(jeq_rri_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZrrci(op_code, ra, rb, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJnzRiStmt(stmt_ *stmt.Stmt) { jnz_ri_stmt := stmt_.JnzRiStmt() op_code := this.ConvertJumpOpCode(jnz_ri_stmt.OpCode()) ra := this.ConvertSrcReg(jnz_ri_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.SUB { imm := int64(0) condition := this.ConvertJumpCondition(jnz_ri_stmt.OpCode()) pc := this.EvaluateProgramCounter(jnz_ri_stmt.Pc()) instruction_.InitZrici(op_code, ra, imm, condition, pc) } else if op_code == instruction.CALL { imm := this.EvaluateProgramCounter(jnz_ri_stmt.Pc()) instruction_.InitZri(op_code, ra, imm) } else { err := errors.New("op code is not valid") panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJumpIStmt(stmt_ *stmt.Stmt) { jump_i_stmt := stmt_.JumpIStmt() op_code := instruction.CALL zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(jump_i_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZri(op_code, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJumpRStmt(stmt_ *stmt.Stmt) { jump_r_stmt := stmt_.JumpRStmt() op_code := instruction.CALL ra := this.ConvertSrcReg(jump_r_stmt.Ra()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitZri(op_code, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLbsRriStmt(stmt_ *stmt.Stmt) { lbs_rri_stmt := stmt_.LbsRriStmt() op_code := this.ConvertLoadOpCode(lbs_rri_stmt.OpCode()) endian := instruction.LITTLE rc := this.ConvertGpReg(lbs_rri_stmt.Rc()) ra := this.ConvertSrcReg(lbs_rri_stmt.Ra()) off := this.EvaluateProgramCounter(lbs_rri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitErri(op_code, endian, rc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLbsSRriStmt(stmt_ *stmt.Stmt) { lbs_s_rri_stmt := stmt_.LbsSRriStmt() op_code := this.ConvertLoadOpCode(lbs_s_rri_stmt.OpCode()) suffix := this.ConvertSuffix(lbs_s_rri_stmt.Suffix(), instruction.ERRI) endian := instruction.LITTLE dc := this.ConvertPairReg(lbs_s_rri_stmt.Dc()) ra := this.ConvertSrcReg(lbs_s_rri_stmt.Ra()) off := this.EvaluateProgramCounter(lbs_s_rri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitSErri(op_code, suffix, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLdDriStmt(stmt_ *stmt.Stmt) { ld_dri_stmt := stmt_.LdDriStmt() op_code := this.ConvertLoadOpCode(ld_dri_stmt.OpCode()) endian := instruction.LITTLE dc := this.ConvertPairReg(ld_dri_stmt.Dc()) ra := this.ConvertSrcReg(ld_dri_stmt.Ra()) off := this.EvaluateProgramCounter(ld_dri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitEdri(op_code, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMovdDdStmt(stmt_ *stmt.Stmt) { movd_dd_stmt := stmt_.MovdDdStmt() op_code := this.ConvertDdciOpCode(movd_dd_stmt.OpCode()) dc := this.ConvertPairReg(movd_dd_stmt.Dc()) db := this.ConvertPairReg(movd_dd_stmt.Db()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitDdci(op_code, dc, db, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveRiciStmt(stmt_ *stmt.Stmt) { move_rici_stmt := stmt_.MoveRiciStmt() op_code := instruction.OR rc := this.ConvertGpReg(move_rici_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_rici_stmt.Imm()) condition := this.ConvertCondition(move_rici_stmt.Condition()) pc := this.EvaluateProgramCounter(move_rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveRiStmt(stmt_ *stmt.Stmt) { move_ri_stmt := stmt_.MoveRiStmt() op_code := instruction.OR rc := this.ConvertGpReg(move_ri_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveSRiciStmt(stmt_ *stmt.Stmt) { move_s_rici_stmt := stmt_.MoveSRiciStmt() op_code := instruction.OR suffix := this.ConvertSuffix(move_s_rici_stmt.Suffix(), instruction.RRICI) dc := this.ConvertPairReg(move_s_rici_stmt.Dc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_s_rici_stmt.Imm()) condition := this.ConvertCondition(move_s_rici_stmt.Condition()) pc := this.EvaluateProgramCounter(move_s_rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveSRiStmt(stmt_ *stmt.Stmt) { move_s_ri_stmt := stmt_.MoveSRiStmt() // NOTE(bongjoon.hyun@gmail.com): move.s is implemented by using and.s:rki op_code := instruction.AND suffix := this.ConvertSuffix(move_s_ri_stmt.Suffix(), instruction.RRI) dc := this.ConvertPairReg(move_s_ri_stmt.Dc()) lneg_reg := new(reg_descriptor.SpRegDescriptor) *lneg_reg = reg_descriptor.LNEG ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(lneg_reg) imm := this.EvaluateProgramCounter(move_s_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRri(op_code, suffix, dc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbIdRiiStmt(stmt_ *stmt.Stmt) { sb_id_rii_stmt := stmt_.SbIdRiiStmt() op_code := this.ConvertStoreOpCode(sb_id_rii_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_id_rii_stmt.Ra()) off := this.EvaluateProgramCounter(sb_id_rii_stmt.Off()) imm := this.EvaluateProgramCounter(sb_id_rii_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbIdRiStmt(stmt_ *stmt.Stmt) { sb_id_ri_stmt := stmt_.SbIdRiStmt() op_code := this.ConvertStoreOpCode(sb_id_ri_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_id_ri_stmt.Ra()) off := this.EvaluateProgramCounter(sb_id_ri_stmt.Off()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbRirStmt(stmt_ *stmt.Stmt) { sb_rir_stmt := stmt_.SbRirStmt() op_code := this.ConvertStoreOpCode(sb_rir_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_rir_stmt.Ra()) off := this.EvaluateProgramCounter(sb_rir_stmt.Off()) rb := this.ConvertSrcReg(sb_rir_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitErir(op_code, endian, ra, off, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSdRidStmt(stmt_ *stmt.Stmt) { sb_rid_stmt := stmt_.SdRidStmt() op_code := this.ConvertStoreOpCode(sb_rid_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_rid_stmt.Ra()) off := this.EvaluateProgramCounter(sb_rid_stmt.Off()) db := this.ConvertPairReg(sb_rid_stmt.Db()) instruction_ := new(instruction.Instruction) instruction_.InitErid(op_code, endian, ra, off, db) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkStopStmt(stmt_ *stmt.Stmt) { op_code := instruction.STOP condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitCi(op_code, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkTimeCfgRStmt(stmt_ *stmt.Stmt) { time_cfg_r_stmt := stmt_.TimeCfgRStmt() op_code := instruction.TIME_CFG ra := this.ConvertSrcReg(time_cfg_r_stmt.Ra()) instruction_ := new(instruction.Instruction) instruction_.InitZr(op_code, ra) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLabelStmt(stmt_ *stmt.Stmt) { label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() label_name := token.Attribute() if label_name != "__sys_used_mram_end" { this.executable.CurSection().CheckoutLabel(label_name) } } func (this *InstructionAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *InstructionAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } func (this *InstructionAssigner) ConvertCiOpCode(op_code *expr.Expr) instruction.OpCode { ci_op_code_expr := op_code.CiOpCodeExpr() token_type := ci_op_code_expr.Token().TokenType() if token_type == lexer.STOP { return instruction.STOP } else { err := errors.New("CI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDdciOpCode(op_code *expr.Expr) instruction.OpCode { ddci_op_code_expr := op_code.DdciOpCodeExpr() token_type := ddci_op_code_expr.Token().TokenType() if token_type == lexer.MOVD { return instruction.MOVD } else if token_type == lexer.SWAPD { return instruction.SWAPD } else { err := errors.New("DDCI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDmaRriOpCode(op_code *expr.Expr) instruction.OpCode { dma_rri_op_code_expr := op_code.DmaRriOpCodeExpr() token_type := dma_rri_op_code_expr.Token().TokenType() if token_type == lexer.LDMA { return instruction.LDMA } else if token_type == lexer.LDMAI { return instruction.LDMAI } else if token_type == lexer.SDMA { return instruction.SDMA } else { err := errors.New("DMA_RRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDrdiciOpCode(op_code *expr.Expr) instruction.OpCode { drdici_op_code_expr := op_code.DrdiciOpCodeExpr() token_type := drdici_op_code_expr.Token().TokenType() if token_type == lexer.DIV_STEP { return instruction.DIV_STEP } else if token_type == lexer.MUL_STEP { return instruction.MUL_STEP } else { err := errors.New("DRDICI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertIOpCode(op_code *expr.Expr) instruction.OpCode { i_op_code_expr := op_code.IOpCodeExpr() token_type := i_op_code_expr.Token().TokenType() if token_type == lexer.FAULT { return instruction.FAULT } else { err := errors.New("I op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRiciOpCode(op_code *expr.Expr) instruction.OpCode { rici_op_code_expr := op_code.RiciOpCodeExpr() token_type := rici_op_code_expr.Token().TokenType() if token_type == lexer.ACQUIRE { return instruction.ACQUIRE } else if token_type == lexer.RELEASE { return instruction.RELEASE } else if token_type == lexer.BOOT { return instruction.BOOT } else if token_type == lexer.RESUME { return instruction.RESUME } else { err := errors.New("I op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertROpCode(op_code *expr.Expr) instruction.OpCode { r_op_code_expr := op_code.ROpCodeExpr() token_type := r_op_code_expr.Token().TokenType() if token_type == lexer.TIME { return instruction.TIME } else if token_type == lexer.NOP { return instruction.NOP } else { err := errors.New("R op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRrOpCode(op_code *expr.Expr) instruction.OpCode { rr_op_code_expr := op_code.RrOpCodeExpr() token_type := rr_op_code_expr.Token().TokenType() if token_type == lexer.CAO { return instruction.CAO } else if token_type == lexer.CLO { return instruction.CLO } else if token_type == lexer.CLS { return instruction.CLS } else if token_type == lexer.CLZ { return instruction.CLZ } else if token_type == lexer.EXTSB { return instruction.EXTSB } else if token_type == lexer.EXTSH { return instruction.EXTSH } else if token_type == lexer.EXTUB { return instruction.EXTUB } else if token_type == lexer.EXTUH { return instruction.EXTUH } else if token_type == lexer.SATS { return instruction.SATS } else if token_type == lexer.TIME_CFG { return instruction.TIME_CFG } else if token_type == lexer.MOVE { return instruction.OR } else if token_type == lexer.NEG { return instruction.SUB } else if token_type == lexer.NOT { return instruction.XOR } else { err := errors.New("RR op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRriOpCode(op_code *expr.Expr) instruction.OpCode { rri_op_code_expr := op_code.RriOpCodeExpr() token_type := rri_op_code_expr.Token().TokenType() if token_type == lexer.ADD { return instruction.ADD } else if token_type == lexer.ADDC { return instruction.ADDC } else if token_type == lexer.AND { return instruction.AND } else if token_type == lexer.ANDN { return instruction.ANDN } else if token_type == lexer.ASR { return instruction.ASR } else if token_type == lexer.CMPB4 { return instruction.CMPB4 } else if token_type == lexer.LSL { return instruction.LSL } else if token_type == lexer.LSL1 { return instruction.LSL1 } else if token_type == lexer.LSL1X { return instruction.LSL1X } else if token_type == lexer.LSLX { return instruction.LSLX } else if token_type == lexer.LSR { return instruction.LSR } else if token_type == lexer.LSR1 { return instruction.LSR1 } else if token_type == lexer.LSR1X { return instruction.LSR1X } else if token_type == lexer.LSRX { return instruction.LSRX } else if token_type == lexer.MUL_SH_SH { return instruction.MUL_SH_SH } else if token_type == lexer.MUL_SH_SL { return instruction.MUL_SH_SL } else if token_type == lexer.MUL_SH_UH { return instruction.MUL_SH_UH } else if token_type == lexer.MUL_SH_UL { return instruction.MUL_SH_UL } else if token_type == lexer.MUL_SL_SH { return instruction.MUL_SL_SH } else if token_type == lexer.MUL_SL_SL { return instruction.MUL_SL_SL } else if token_type == lexer.MUL_SL_UH { return instruction.MUL_SL_UH } else if token_type == lexer.MUL_SL_UL { return instruction.MUL_SL_UL } else if token_type == lexer.MUL_UH_UH { return instruction.MUL_UH_UH } else if token_type == lexer.MUL_UH_UL { return instruction.MUL_UH_UL } else if token_type == lexer.MUL_UL_UH { return instruction.MUL_UL_UH } else if token_type == lexer.MUL_UL_UL { return instruction.MUL_UL_UL } else if token_type == lexer.NAND { return instruction.NAND } else if token_type == lexer.NOR { return instruction.NOR } else if token_type == lexer.NXOR { return instruction.NXOR } else if token_type == lexer.OR { return instruction.OR } else if token_type == lexer.ORN { return instruction.ORN } else if token_type == lexer.ROL { return instruction.ROL } else if token_type == lexer.ROR { return instruction.ROR } else if token_type == lexer.RSUB { return instruction.RSUB } else if token_type == lexer.RSUBC { return instruction.RSUBC } else if token_type == lexer.SUB { return instruction.SUB } else if token_type == lexer.SUBC { return instruction.SUBC } else if token_type == lexer.XOR { return instruction.XOR } else if token_type == lexer.CALL { return instruction.CALL } else if token_type == lexer.HASH { return instruction.HASH } else { err := errors.New("RRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRrriOpCode(op_code *expr.Expr) instruction.OpCode { rrri_op_code_expr := op_code.RrriOpCodeExpr() token_type := rrri_op_code_expr.Token().TokenType() if token_type == lexer.LSL_ADD { return instruction.LSL_ADD } else if token_type == lexer.LSL_SUB { return instruction.LSL_SUB } else if token_type == lexer.LSR_ADD { return instruction.LSR_ADD } else if token_type == lexer.ROL_ADD { return instruction.ROL_ADD } else { err := errors.New("RRRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertLoadOpCode(op_code *expr.Expr) instruction.OpCode { load_op_code_expr := op_code.LoadOpCodeExpr() token_type := load_op_code_expr.Token().TokenType() if token_type == lexer.LBS { return instruction.LBS } else if token_type == lexer.LBU { return instruction.LBU } else if token_type == lexer.LD { return instruction.LD } else if token_type == lexer.LHS { return instruction.LHS } else if token_type == lexer.LHU { return instruction.LHU } else if token_type == lexer.LW { return instruction.LW } else { err := errors.New("load op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertStoreOpCode(op_code *expr.Expr) instruction.OpCode { store_op_code_expr := op_code.StoreOpCodeExpr() token_type := store_op_code_expr.Token().TokenType() if token_type == lexer.SB { return instruction.SB } else if token_type == lexer.SB_ID { return instruction.SB_ID } else if token_type == lexer.SD { return instruction.SD } else if token_type == lexer.SD_ID { return instruction.SD_ID } else if token_type == lexer.SH { return instruction.SH } else if token_type == lexer.SH_ID { return instruction.SH_ID } else if token_type == lexer.SW { return instruction.SW } else if token_type == lexer.SW_ID { return instruction.SW_ID } else { err := errors.New("store op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertJumpOpCode(op_code *expr.Expr) instruction.OpCode { jump_op_code_expr := op_code.JumpOpCodeExpr() token_type := jump_op_code_expr.Token().TokenType() if token_type == lexer.JEQ { return instruction.SUB } else if token_type == lexer.JGES { return instruction.SUB } else if token_type == lexer.JGEU { return instruction.SUB } else if token_type == lexer.JGTS { return instruction.SUB } else if token_type == lexer.JGTU { return instruction.SUB } else if token_type == lexer.JLES { return instruction.SUB } else if token_type == lexer.JLEU { return instruction.SUB } else if token_type == lexer.JLTS { return instruction.SUB } else if token_type == lexer.JLTU { return instruction.SUB } else if token_type == lexer.JNEQ { return instruction.SUB } else if token_type == lexer.JNZ { return instruction.SUB } else if token_type == lexer.JUMP { return instruction.CALL } else if token_type == lexer.JZ { return instruction.SUB } else { err := errors.New("jump op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertSuffix( suffix *expr.Expr, base instruction.Suffix, ) instruction.Suffix { suffix_expr := suffix.SuffixExpr() token_type := suffix_expr.Token().TokenType() if token_type == lexer.S { if base == instruction.ERRI { return instruction.S_ERRI } else if base == instruction.RCI { return instruction.S_RCI } else if base == instruction.RIRCI { return instruction.S_RIRCI } else if base == instruction.RIRC { return instruction.S_RIRC } else if base == instruction.RRCI { return instruction.S_RRCI } else if base == instruction.RRC { return instruction.S_RRC } else if base == instruction.RRICI { return instruction.S_RRICI } else if base == instruction.RRIC { return instruction.S_RRIC } else if base == instruction.RRI { return instruction.S_RRI } else if base == instruction.RRRCI { return instruction.S_RRRCI } else if base == instruction.RRRC { return instruction.S_RRRC } else if base == instruction.RRRICI { return instruction.S_RRRICI } else if base == instruction.RRRI { return instruction.S_RRRI } else if base == instruction.RRR { return instruction.S_RRR } else if base == instruction.RR { return instruction.S_RR } else if base == instruction.R { return instruction.S_R } else { err := errors.New("base is not valid") panic(err) } } else if token_type == lexer.U { if base == instruction.ERRI { return instruction.U_ERRI } else if base == instruction.RCI { return instruction.U_RCI } else if base == instruction.RIRCI { return instruction.U_RIRCI } else if base == instruction.RIRC { return instruction.U_RIRC } else if base == instruction.RRCI { return instruction.U_RRCI } else if base == instruction.RRC { return instruction.U_RRC } else if base == instruction.RRICI { return instruction.U_RRICI } else if base == instruction.RRIC { return instruction.U_RRIC } else if base == instruction.RRI { return instruction.U_RRI } else if base == instruction.RRRCI { return instruction.U_RRRCI } else if base == instruction.RRRC { return instruction.U_RRRC } else if base == instruction.RRRICI { return instruction.U_RRRICI } else if base == instruction.RRRI { return instruction.U_RRRI } else if base == instruction.RRR { return instruction.U_RRR } else if base == instruction.RR { return instruction.U_RR } else if base == instruction.R { return instruction.U_R } else { err := errors.New("base is not valid") panic(err) } } else { err := errors.New("suffix is not valid") panic(err) } } func (this *InstructionAssigner) ConvertGpReg(expr_ *expr.Expr) *reg_descriptor.GpRegDescriptor { src_reg_expr := expr_.SrcRegExpr() index, err := strconv.Atoi(src_reg_expr.Token().Attribute()[1:]) if err != nil { panic(err) } gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) return gp_reg_descriptor } func (this *InstructionAssigner) ConvertSrcReg(expr_ *expr.Expr) *reg_descriptor.SrcRegDescriptor { src_reg_expr := expr_.SrcRegExpr() token := src_reg_expr.Token() token_type := token.TokenType() if token_type == lexer.GP_REG { gp_reg_descriptor := this.ConvertGpReg(expr_) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitGpRegDescriptor(gp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ZERO_REG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ZERO src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ONE { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ONE src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID2 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID2 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID4 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID4 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID8 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID8 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.LNEG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.LNEG src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.MNEG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.MNEG src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else { err := errors.New("src reg is not valid") panic(err) } } func (this *InstructionAssigner) ConvertPairReg( token *lexer.Token, ) *reg_descriptor.PairRegDescriptor { index, err := strconv.Atoi(token.Attribute()[1:]) if err != nil { panic(err) } pair_reg_descriptor := new(reg_descriptor.PairRegDescriptor) pair_reg_descriptor.Init(index) return pair_reg_descriptor } func (this *InstructionAssigner) ConvertCondition(expr_ *expr.Expr) cc.Condition { condition_expr := expr_.ConditionExpr() token := condition_expr.Token() token_type := token.TokenType() if token_type == lexer.TRUE { return cc.TRUE } else if token_type == lexer.FALSE { return cc.FALSE } else if token_type == lexer.Z { return cc.Z } else if token_type == lexer.NZ { return cc.NZ } else if token_type == lexer.E { return cc.E } else if token_type == lexer.O { return cc.O } else if token_type == lexer.PL { return cc.PL } else if token_type == lexer.MI { return cc.MI } else if token_type == lexer.OV { return cc.OV } else if token_type == lexer.NOV { return cc.NOV } else if token_type == lexer.C { return cc.C } else if token_type == lexer.NC { return cc.NC } else if token_type == lexer.SZ { return cc.SZ } else if token_type == lexer.SNZ { return cc.SNZ } else if token_type == lexer.SPL { return cc.SPL } else if token_type == lexer.SMI { return cc.SMI } else if token_type == lexer.SO { return cc.SO } else if token_type == lexer.SE { return cc.SE } else if token_type == lexer.NC5 { return cc.NC5 } else if token_type == lexer.NC6 { return cc.NC6 } else if token_type == lexer.NC7 { return cc.NC7 } else if token_type == lexer.NC8 { return cc.NC8 } else if token_type == lexer.NC9 { return cc.NC9 } else if token_type == lexer.NC10 { return cc.NC10 } else if token_type == lexer.NC11 { return cc.NC11 } else if token_type == lexer.NC12 { return cc.NC12 } else if token_type == lexer.NC13 { return cc.NC13 } else if token_type == lexer.NC14 { return cc.NC14 } else if token_type == lexer.MAX { return cc.MAX } else if token_type == lexer.NMAX { return cc.NMAX } else if token_type == lexer.SH32 { return cc.SH32 } else if token_type == lexer.NSH32 { return cc.NSH32 } else if token_type == lexer.EQ { return cc.EQ } else if token_type == lexer.NEQ { return cc.NEQ } else if token_type == lexer.LTU { return cc.LTU } else if token_type == lexer.LEU { return cc.LEU } else if token_type == lexer.GTU { return cc.GTU } else if token_type == lexer.GEU { return cc.GEU } else if token_type == lexer.LTS { return cc.LTS } else if token_type == lexer.LES { return cc.LES } else if token_type == lexer.GTS { return cc.GTS } else if token_type == lexer.GES { return cc.GES } else if token_type == lexer.XZ { return cc.XZ } else if token_type == lexer.XNZ { return cc.XNZ } else if token_type == lexer.XLEU { return cc.XLEU } else if token_type == lexer.XGTU { return cc.XGTU } else if token_type == lexer.XLES { return cc.XLES } else if token_type == lexer.XGTS { return cc.XGTS } else if token_type == lexer.SMALL { return cc.SMALL } else if token_type == lexer.LARGE { return cc.LARGE } else { err := errors.New("condition is not valid") panic(err) } } func (this *InstructionAssigner) ConvertEndian(expr_ *expr.Expr) instruction.Endian { endian_expr := expr_.EndianExpr() token := endian_expr.Token() token_type := token.TokenType() if token_type == lexer.LITTLE { return instruction.LITTLE } else if token_type == lexer.BIG { return instruction.BIG } else { err := errors.New("endian is not valid") panic(err) } } func (this *InstructionAssigner) ConvertJumpCondition(op_code *expr.Expr) cc.Condition { jump_op_code_expr := op_code.JumpOpCodeExpr() token_type := jump_op_code_expr.Token().TokenType() if token_type == lexer.JEQ { return cc.Z } else if token_type == lexer.JGES { return cc.GES } else if token_type == lexer.JGEU { return cc.GEU } else if token_type == lexer.JGTS { return cc.GTS } else if token_type == lexer.JGTU { return cc.GTU } else if token_type == lexer.JLES { return cc.LES } else if token_type == lexer.JLEU { return cc.LEU } else if token_type == lexer.JLTS { return cc.LTS } else if token_type == lexer.JLTU { return cc.LTU } else if token_type == lexer.JNEQ { return cc.NZ } else if token_type == lexer.JNZ { return cc.NZ } else if token_type == lexer.JZ { return cc.Z } else { err := errors.New("jump op code is not valid") panic(err) } } func (this *InstructionAssigner) EvaluateProgramCounter(expr_ *expr.Expr) int64 { program_counter_expr := expr_.ProgramCounterExpr() child_expr := program_counter_expr.Expr() child_expr_type := child_expr.ExprType() if child_expr_type == expr.PRIMARY { return this.EvaluatePrimary(child_expr) } else if child_expr_type == expr.NEGATIVE_NUMBER { return this.EvaluateNegativeNumber(child_expr) } else if child_expr_type == expr.BINARY_ADD { return this.EvaluateBinaryAdd(child_expr) } else if child_expr_type == expr.BINARY_SUB { return this.EvaluateBinarySub(child_expr) } else { err := errors.New("program counter expr is not valid") panic(err) } } func (this *InstructionAssigner) EvaluatePrimary(expr_ *expr.Expr) int64 { primary_expr := expr_.PrimaryExpr() token := primary_expr.Token() token_type := token.TokenType() if token_type == lexer.POSITIVIE_NUMBER { return this.EvaluatePositiveNumber(token) } else if token_type == lexer.HEX_NUMBER { return this.EvaluateHexNumber(token) } else if token_type == lexer.IDENTIFIER { return this.EvaluateIdentifier(token) } else { err := errors.New("primary expr is not valid") panic(err) } } func (this *InstructionAssigner) EvaluatePositiveNumber(token *lexer.Token) int64 { value, err := strconv.ParseInt(token.Attribute(), 10, 64) if err != nil { panic(err) } return value } func (this *InstructionAssigner) EvaluateHexNumber(token *lexer.Token) int64 { attribute := token.Attribute() var value int64 var err error if attribute[:2] == "0x" { value, err = strconv.ParseInt(attribute[2:], 16, 64) } else { value, err = strconv.ParseInt(attribute, 16, 64) } if err != nil { panic(err) } return value } func (this *InstructionAssigner) EvaluateIdentifier(token *lexer.Token) int64 { name := token.Attribute() label := this.executable.Label(name) linker_constant := this.linker_script.LinkerConstant(name) if label != nil { if linker_constant != nil { err := errors.New("label and linker constant both exist") panic(err) } return label.Address() } else if linker_constant != nil { return linker_constant.Value() } else { err := errors.New("label and linker constant do not exist") panic(err) } } func (this *InstructionAssigner) EvaluateNegativeNumber(expr_ *expr.Expr) int64 { negative_number_expr := expr_.NegativeNumberExpr() return -this.EvaluatePositiveNumber(negative_number_expr.Token()) } func (this *InstructionAssigner) EvaluateBinaryAdd(expr_ *expr.Expr) int64 { binary_add_expr := expr_.BinaryAddExpr() is_operand1_nr_tasklets := binary_add_expr.Operand1(). PrimaryExpr(). Token(). Attribute() == "NR_TASKLETS" is_operand2_number := binary_add_expr.Operand2(). PrimaryExpr(). Token(). TokenType() != lexer.IDENTIFIER if !is_operand1_nr_tasklets && is_operand2_number { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) return this.EvaluatePrimary( binary_add_expr.Operand1(), ) + iram_data_size*this.EvaluatePrimary( binary_add_expr.Operand2(), ) } else { return this.EvaluatePrimary( binary_add_expr.Operand1(), ) + this.EvaluatePrimary( binary_add_expr.Operand2(), ) } } func (this *InstructionAssigner) EvaluateBinarySub(expr_ *expr.Expr) int64 { binary_sub_expr := expr_.BinarySubExpr() is_operand1_nr_tasklets := binary_sub_expr.Operand1(). PrimaryExpr(). Token(). Attribute() == "NR_TASKLETS" is_operand2_number := binary_sub_expr.Operand2(). PrimaryExpr(). Token(). TokenType() != lexer.IDENTIFIER if !is_operand1_nr_tasklets && is_operand2_number { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) return this.EvaluatePrimary( binary_sub_expr.Operand1(), ) - iram_data_size*this.EvaluatePrimary( binary_sub_expr.Operand2(), ) } else { return this.EvaluatePrimary( binary_sub_expr.Operand1(), ) - this.EvaluatePrimary( binary_sub_expr.Operand2(), ) } } func (this *InstructionAssigner) EvaluateSectionName(expr_ *expr.Expr) int64 { section_name := this.ConvertSectionName(expr_) name := "" return this.executable.Section(section_name, name).Address() } func (this *InstructionAssigner) IsZeroReg(expr_ *expr.Expr) bool { src_reg_expr := expr_.SrcRegExpr() return src_reg_expr.Token().TokenType() == lexer.ZERO_REG } ================================================ FILE: golang/uPIMulator/src/linker/logic/label_assigner.go ================================================ package logic import ( "errors" "strconv" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" "uPIMulator/src/misc" ) type LabelAssigner struct { executable *kernel.Executable walker *parser.Walker } func (this *LabelAssigner) Init() { this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback(stmt.ASCII, this.WalkAsciiStmt) this.walker.RegisterStmtCallback(stmt.ASCIZ, this.WalkAscizStmt) this.walker.RegisterStmtCallback(stmt.BYTE, this.WalkByteStmt) this.walker.RegisterStmtCallback(stmt.LONG_PROGRAM_COUNTER, this.WalkLongProgramCounterStmt) this.walker.RegisterStmtCallback(stmt.LONG_SECTION_NAME, this.WalkLongSectionNameStmt) this.walker.RegisterStmtCallback(stmt.QUAD, this.WalkQuadStmt) this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.SHORT, this.WalkShortStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) this.walker.RegisterStmtCallback(stmt.ZERO_DOUBLE_NUMBER, this.WalkZeroDoubleNumberStmt) this.walker.RegisterStmtCallback(stmt.ZERO_SINGLE_NUMBER, this.WalkZeroSingleNumberStmt) this.walker.RegisterStmtCallback(stmt.CI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DDCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DMA_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DRDICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.EDRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERID, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.I, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.NOP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRIC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_ERRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RIRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RIRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRIC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.BKP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.BOOT_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.CALL_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.CALL_RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DIV_STEP_DRDI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JNZ_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JUMP_I, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JUMP_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LBS_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LBS_S_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LD_DRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVD_DD, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_RIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SD_RID, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.STOP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.TIME_CFG_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *LabelAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *LabelAssigner) WalkAsciiStmt(stmt_ *stmt.Stmt) { ascii_stmt := stmt_.AsciiStmt() token := ascii_stmt.Token() attribute := token.Attribute() // TODO(bongjoon.hyun@gmail.com): decode octal code cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + int64(len(attribute)) - 2) } func (this *LabelAssigner) WalkAscizStmt(stmt_ *stmt.Stmt) { asciz_stmt := stmt_.AscizStmt() token := asciz_stmt.Token() attribute := token.Attribute() cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + int64(len(attribute)) - 1) } func (this *LabelAssigner) WalkByteStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 1) } func (this *LabelAssigner) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 4) } func (this *LabelAssigner) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 4) } func (this *LabelAssigner) WalkQuadStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 8) } func (this *LabelAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) section_flags := this.ConvertSectionFlags(section_identifier_number_stmt.Token()) section_type := this.ConvertSectionType(section_identifier_number_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) section_flags := this.ConvertSectionFlags(section_identifier_stmt.Token()) section_type := this.ConvertSectionType(section_identifier_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_flags := this.ConvertSectionFlags(section_stack_sizes_stmt.Token()) section_type := this.ConvertSectionType(section_stack_sizes_stmt.Expr1()) section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" section_flags := this.ConvertSectionFlags(section_string_number_stmt.Token()) section_type := this.ConvertSectionType(section_string_number_stmt.Expr2()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" section_flags := this.ConvertSectionFlags(section_string_stmt.Token()) section_type := this.ConvertSectionType(section_string_stmt.Expr2()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkShortStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 2) } func (this *LabelAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" section_flags := make(map[kernel.SectionFlag]bool, 0) section_type := kernel.PROGBITS if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() program_counter_expr := zero_double_number_stmt.Expr1().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() attribute := token.Attribute() size, err := strconv.ParseInt(attribute, 10, 64) if err != nil { panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + size) } func (this *LabelAssigner) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() program_counter_expr := zero_single_number_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() attribute := token.Attribute() size, err := strconv.ParseInt(attribute, 10, 64) if err != nil { panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + size) } func (this *LabelAssigner) WalkInstructionStmt(stmt_ *stmt.Stmt) { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_width := config_loader.IramDataWidth() instruction_size := int64(iram_data_width / 8) cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + instruction_size) } func (this *LabelAssigner) WalkLabelStmt(stmt_ *stmt.Stmt) { label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() label_name := token.Attribute() if label_name != "__sys_used_mram_end" { if this.executable.CurSection().Label(label_name) == nil { this.executable.CurSection().AppendLabel(label_name) } this.executable.CurSection().CheckoutLabel(label_name) } } func (this *LabelAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *LabelAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } func (this *LabelAssigner) ConvertSectionFlags(token *lexer.Token) map[kernel.SectionFlag]bool { attribute := token.Attribute() section_flags := make(map[kernel.SectionFlag]bool, 0) for i := 1; i < len(attribute)-1; i++ { if attribute[i] == 'a' { section_flags[kernel.ALLOC] = true } else if attribute[i] == 'w' { section_flags[kernel.WRITE] = true } else if attribute[i] == 'x' { section_flags[kernel.EXECINSTR] = true } else if attribute[i] == 'o' { section_flags[kernel.LINK_ORDER] = true } else if attribute[i] == 'M' { section_flags[kernel.MERGE] = true } else if attribute[i] == 'S' { section_flags[kernel.STRINGS] = true } else { err := errors.New("section flag is not valid") panic(err) } } return section_flags } func (this *LabelAssigner) ConvertSectionType(expr_ *expr.Expr) kernel.SectionType { section_type_expr := expr_.SectionTypeExpr() token := section_type_expr.Token() token_type := token.TokenType() if token_type == lexer.PROGBITS { return kernel.PROGBITS } else if token_type == lexer.NOBITS { return kernel.NOBITS } else { err := errors.New("section type is not valid") panic(err) } } ================================================ FILE: golang/uPIMulator/src/linker/logic/linker_constant.go ================================================ package logic type LinkerConstant struct { name string value int64 } func (this *LinkerConstant) Init(name string) { this.name = name this.value = 0 } func (this *LinkerConstant) Name() string { return this.name } func (this *LinkerConstant) Value() int64 { return this.value } func (this *LinkerConstant) SetValue(value int64) { this.value = value } ================================================ FILE: golang/uPIMulator/src/linker/logic/linker_script.go ================================================ package logic import ( "errors" "fmt" "math" "strconv" "strings" "uPIMulator/src/linker/kernel" "uPIMulator/src/misc" ) type LinkerScript struct { command_line_parser *misc.CommandLineParser num_tasklets int min_access_granularity int64 linker_constants map[string]*LinkerConstant } func (this *LinkerScript) Init(command_line_parser *misc.CommandLineParser) { this.command_line_parser = command_line_parser this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.linker_constants = make(map[string]*LinkerConstant, 0) this.InitLinkerConstants() } func (this *LinkerScript) Assign(executable *kernel.Executable) { this.AssignAtomic(executable) this.AssignIram(executable) this.AssignWram(executable) this.AssignMram(executable) } func (this *LinkerScript) HasLinkerConstant(name string) bool { _, found := this.linker_constants[name] return found } func (this *LinkerScript) LinkerConstant(name string) *LinkerConstant { return this.linker_constants[name] } func (this *LinkerScript) InitLinkerConstants() { config_loader := new(misc.ConfigLoader) config_loader.Init() max_num_tasklets := config_loader.MaxNumTasklets() stack_size := config_loader.StackSize() this.linker_constants["NR_TASKLETS"] = new(LinkerConstant) this.linker_constants["NR_TASKLETS"].Init("NR_TASKLETS") this.linker_constants["NR_TASKLETS"].SetValue(int64(this.num_tasklets)) for i := 0; i < max_num_tasklets; i++ { stack_size_tasklet := "STACK_SIZE_TASKLET_" + strconv.Itoa(i) this.linker_constants[stack_size_tasklet] = new(LinkerConstant) this.linker_constants[stack_size_tasklet].Init(stack_size_tasklet) this.linker_constants[stack_size_tasklet].SetValue(stack_size) } this.linker_constants["__atomic_start_addr"] = new(LinkerConstant) this.linker_constants["__atomic_start_addr"].Init("__atomic_start_addr") this.linker_constants["__atomic_used_addr"] = new(LinkerConstant) this.linker_constants["__atomic_used_addr"].Init("__atomic_used_addr") this.linker_constants["__atomic_end_addr"] = new(LinkerConstant) this.linker_constants["__atomic_end_addr"].Init("__atomic_end_addr") this.linker_constants["__rodata_start_addr"] = new(LinkerConstant) this.linker_constants["__rodata_start_addr"].Init("__rodata_start_addr") this.linker_constants["__rodata_end_addr"] = new(LinkerConstant) this.linker_constants["__rodata_end_addr"].Init("__rodata_end_addr") for i := 0; i < max_num_tasklets; i++ { sys_stack_thread := "__sys_stack_thread_" + strconv.Itoa(i) this.linker_constants[sys_stack_thread] = new(LinkerConstant) this.linker_constants[sys_stack_thread].Init(sys_stack_thread) } this.linker_constants["__sw_cache_buffer"] = new(LinkerConstant) this.linker_constants["__sw_cache_buffer"].Init("__sw_cache_buffer") this.linker_constants["__sys_heap_pointer_reset"] = new(LinkerConstant) this.linker_constants["__sys_heap_pointer_reset"].Init("__sys_heap_pointer_reset") this.linker_constants["__sys_used_mram_end"] = new(LinkerConstant) this.linker_constants["__sys_used_mram_end"].Init("__sys_used_mram_end") } func (this *LinkerScript) AssignAtomic(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.AtomicOffset() this.linker_constants["__atomic_start_addr"].SetValue(cur_address) this.linker_constants["__atomic_used_addr"].SetValue(cur_address) for section, _ := range executable.Sections(kernel.ATOMIC) { section.SetAddress(cur_address) cur_address += section.Size() } this.linker_constants["__atomic_end_addr"].SetValue(cur_address) if cur_address >= config_loader.AtomicOffset()+config_loader.AtomicSize() { err := errors.New("address is larger than the atomic end address") panic(err) } } func (this *LinkerScript) AssignIram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.IramOffset() bootstrap := executable.Section(kernel.TEXT, "__bootstrap") if bootstrap == nil { err := errors.New("bootstrap is not found") panic(err) } bootstrap.SetAddress(cur_address) cur_address += bootstrap.Size() text_default := executable.Section(kernel.TEXT, "") if text_default != nil { text_default.SetAddress(cur_address) cur_address += text_default.Size() } for section, _ := range executable.Sections(kernel.TEXT) { if section.Name() != "__bootstrap" && section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } if cur_address >= config_loader.IramOffset()+config_loader.IramSize() { err := errors.New("address is larger than the IRAM end address") panic(err) } } func (this *LinkerScript) AssignWram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.WramOffset() sys_zero := executable.Section(kernel.DATA, "__sys_zero") if sys_zero != nil { sys_zero.SetAddress(cur_address) cur_address += sys_zero.Size() } immediate_memory := executable.Section(kernel.DATA, "immediate_memory") if immediate_memory != nil { immediate_memory.SetAddress(cur_address) cur_address += immediate_memory.Size() } for section, _ := range executable.Sections(kernel.DATA) { if strings.Contains(section.Name(), "immediate_memory.") { section.SetAddress(cur_address) cur_address += section.Size() } } this.linker_constants["__rodata_start_addr"].SetValue(cur_address) rodata_default := executable.Section(kernel.RODATA, "") if rodata_default != nil { rodata_default.SetAddress(cur_address) cur_address += rodata_default.Size() } for section, _ := range executable.Sections(kernel.RODATA) { if section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } this.linker_constants["__rodata_end_addr"].SetValue(cur_address) bss_default := executable.Section(kernel.BSS, "") if bss_default != nil { bss_default.SetAddress(cur_address) cur_address += bss_default.Size() } for section, _ := range executable.Sections(kernel.BSS) { if section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } sys_keep := executable.Section(kernel.DATA, "__sys_keep") if sys_keep != nil { sys_keep.SetAddress(cur_address) cur_address += sys_keep.Size() } data_default := executable.Section(kernel.DATA, "") if data_default != nil { data_default.SetAddress(cur_address) cur_address += data_default.Size() } for section, _ := range executable.Sections(kernel.DATA) { if section.Name() != "__sys_zero" && section.Name() != "__sys_keep" && !strings.Contains(section.Name(), "immediate_memory") && section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } // TODO(bongjoon.hyun@gmail.com): figure out ".data.__sys_host" section dpu_host := executable.Section(kernel.DPU_HOST, "") if dpu_host != nil { dpu_host.SetAddress(cur_address) cur_address += dpu_host.Size() } // TODO(bongjoon.hyun@gmail.com): figure out ".data.__sys_profilng" section // TODO(bongjoon.hyun@gmail.com): figure out ".data.stacks" section for i := 0; i < config_loader.MaxNumTasklets(); i++ { sys_stack_thread := "__sys_stack_thread_" + strconv.Itoa(i) this.linker_constants[sys_stack_thread].SetValue(cur_address) stack_size_tasklet := "STACK_SIZE_TASKLET_" + strconv.Itoa(i) cur_address += this.linker_constants[stack_size_tasklet].Value() } // TODO(bongjoon.hyun@gmail.com): figure out ".data.sw_cache" section this.linker_constants["__sw_cache_buffer"].SetValue(cur_address) cur_address += int64(8 * config_loader.MaxNumTasklets()) // TODO(bongjoon.hyun@gmail.com): figure out ".data.heap_pointer_reset" section cur_address = int64( math.Ceil(float64(cur_address)/float64(this.min_access_granularity)), ) * int64( this.min_access_granularity, ) this.linker_constants["__sys_heap_pointer_reset"].SetValue(cur_address) if cur_address >= config_loader.WramOffset()+config_loader.WramSize() { err := errors.New("address is larger than the WRAM end address") panic(err) } } func (this *LinkerScript) AssignMram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.MramOffset() for section, _ := range executable.Sections(kernel.DEBUG_ABBREV) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_FRAME) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_INFO) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_LINE) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_LOC) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_RANGES) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_STR) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.STACK_SIZES) { section.SetAddress(cur_address) cur_address += section.Size() } noinit := executable.Section(kernel.MRAM, "noinit") if noinit != nil { noinit.SetAddress(cur_address) cur_address += noinit.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.") && !strings.Contains(section.Name(), "noinit.keep") { section.SetAddress(cur_address) cur_address += section.Size() } } noinit_keep := executable.Section(kernel.MRAM, "noinit.keep") if noinit_keep != nil { noinit_keep.SetAddress(cur_address) cur_address += noinit_keep.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.keep") && !strings.Contains(section.Name(), "noinit.keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } mram_default := executable.Section(kernel.MRAM, "") if mram_default != nil { mram_default.SetAddress(cur_address) cur_address += mram_default.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if section.Name() != "" && !strings.Contains(section.Name(), "noinit") && !strings.Contains(section.Name(), "keep") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "keep") && !strings.Contains(section.Name(), "keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } cur_address = int64( math.Ceil(float64(cur_address)/float64(this.min_access_granularity)), ) * this.min_access_granularity this.linker_constants["__sys_used_mram_end"].SetValue(cur_address) if cur_address >= config_loader.MramOffset()+config_loader.MramSize() { err := errors.New("address is larger than the MRAM end address") panic(err) } } func (this *LinkerScript) DumpValues(path string) { lines := make([]string, 0) for _, linker_constant := range this.linker_constants { line := fmt.Sprintf("%s: %d", linker_constant.Name(), linker_constant.Value()) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } ================================================ FILE: golang/uPIMulator/src/linker/logic/liveness_analyzer.go ================================================ package logic import ( "errors" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" ) type LivenessAnalyzer struct { liveness *kernel.Liveness walker *parser.Walker } func (this *LivenessAnalyzer) Init() { this.liveness = new(kernel.Liveness) this.liveness.Init() this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterExprCallback(expr.PRIMARY, this.WalkPrimaryExpr) this.walker.RegisterStmtCallback(stmt.GLOBAL, this.WalkGlobalStmt) this.walker.RegisterStmtCallback(stmt.SET, this.WalkSetStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *LivenessAnalyzer) Analyze(relocatable *kernel.Relocatable) *kernel.Liveness { this.walker.Walk(relocatable.Ast()) return this.liveness } func (this *LivenessAnalyzer) WalkPrimaryExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PRIMARY { err := errors.New("expr type is not primary") panic(err) } primary_expr := expr_.PrimaryExpr() token := primary_expr.Token() if token.TokenType() == lexer.IDENTIFIER { this.liveness.AddUse(token.Attribute()) } } func (this *LivenessAnalyzer) WalkGlobalStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.GLOBAL { err := errors.New("stmt type is not global") panic(err) } global_stmt := stmt_.GlobalStmt() program_counter_expr := global_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute != "__sys_used_mram_end" { this.liveness.AddGlobalSymbol(attribute) } } func (this *LivenessAnalyzer) WalkSetStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SET { err := errors.New("stmt type is not set") panic(err) } set_stmt := stmt_.SetStmt() program_counter_expr1 := set_stmt.Expr1().ProgramCounterExpr() program_counter_expr2 := set_stmt.Expr2().ProgramCounterExpr() primary_expr1 := program_counter_expr1.Expr().PrimaryExpr() primary_expr2 := program_counter_expr2.Expr().PrimaryExpr() token1 := primary_expr1.Token() token2 := primary_expr2.Token() if token1.TokenType() != lexer.IDENTIFIER { err := errors.New("token1 type is not identifier") panic(err) } if token2.TokenType() != lexer.IDENTIFIER { err := errors.New("token2 type is not identifier") panic(err) } this.liveness.AddDef(token1.Attribute()) this.liveness.AddUse(token2.Attribute()) } func (this *LivenessAnalyzer) WalkLabelStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LABEL { err := errors.New("stmt type is not label") panic(err) } label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute != "__sys_used_mram_end" { this.liveness.AddDef(attribute) } } ================================================ FILE: golang/uPIMulator/src/linker/logic/set_assigner.go ================================================ package logic import ( "errors" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" ) type SetAssigner struct { executable *kernel.Executable walker *parser.Walker } func (this *SetAssigner) Init() { this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) } func (this *SetAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *SetAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSetStmt(stmt_ *stmt.Stmt) { set_stmt := stmt_.SetStmt() program_counter_expr1 := set_stmt.Expr1().ProgramCounterExpr() program_counter_expr2 := set_stmt.Expr2().ProgramCounterExpr() primary_expr1 := program_counter_expr1.Expr().PrimaryExpr() primary_expr2 := program_counter_expr2.Expr().PrimaryExpr() token1 := primary_expr1.Token() token2 := primary_expr2.Token() attribute1 := token1.Attribute() attribute2 := token2.Attribute() src_label := this.executable.CurSection().Label(attribute1) if this.executable.CurSection().Label(attribute2) == nil { this.executable.CurSection().AppendLabel(attribute2) } dst_label := this.executable.CurSection().Label(attribute2) dst_label.SetAddress(src_label.Address()) } func (this *SetAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *SetAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } ================================================ FILE: golang/uPIMulator/src/linker/parse_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/linker/kernel" "uPIMulator/src/linker/parser" ) type ParseJob struct { relocatable *kernel.Relocatable } func (this *ParseJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *ParseJob) Execute() { fmt.Printf("Parsing %s...\n", this.relocatable.Path()) parser_ := new(parser.Parser) parser_.Init() ast := parser_.Parse(this.relocatable.TokenStream()) this.relocatable.SetAst(ast) } ================================================ FILE: golang/uPIMulator/src/linker/parser/ast.go ================================================ package parser import ( "uPIMulator/src/linker/parser/stmt" ) type Ast struct { stmts []*stmt.Stmt } func (this *Ast) Init(stmts []*stmt.Stmt) { this.stmts = stmts } func (this *Ast) Size() int { return len(this.stmts) } func (this *Ast) Get(pos int) *stmt.Stmt { return this.stmts[pos] } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/binary_add_expr.go ================================================ package expr import ( "errors" ) type BinaryAddExpr struct { operand1 *Expr operand2 *Expr } func (this *BinaryAddExpr) Init(operand1 *Expr, operand2 *Expr) { if operand1.ExprType() != PRIMARY { err := errors.New("operand1 is not a primary expr") panic(err) } if operand2.ExprType() != PRIMARY { err := errors.New("operand2 is not a primary expr") panic(err) } this.operand1 = operand1 this.operand2 = operand2 } func (this *BinaryAddExpr) Operand1() *Expr { return this.operand1 } func (this *BinaryAddExpr) Operand2() *Expr { return this.operand2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/binary_sub_expr.go ================================================ package expr import ( "errors" ) type BinarySubExpr struct { operand1 *Expr operand2 *Expr } func (this *BinarySubExpr) Init(operand1 *Expr, operand2 *Expr) { if operand1.ExprType() != PRIMARY { err := errors.New("operand1 is not a primary expr") panic(err) } if operand2.ExprType() != PRIMARY { err := errors.New("operand2 is not a primary expr") panic(err) } this.operand1 = operand1 this.operand2 = operand2 } func (this *BinarySubExpr) Operand1() *Expr { return this.operand1 } func (this *BinarySubExpr) Operand2() *Expr { return this.operand2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/ci_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type CiOpCodeExpr struct { token *lexer.Token } func (this *CiOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.STOP { err := errors.New("token type is not a CI op code") panic(err) } this.token = token } func (this *CiOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/condition_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type ConditionExpr struct { token *lexer.Token } func (this *ConditionExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.TRUE && token_type != lexer.FALSE && token_type != lexer.Z && token_type != lexer.NZ && token_type != lexer.E && token_type != lexer.O && token_type != lexer.PL && token_type != lexer.MI && token_type != lexer.OV && token_type != lexer.NOV && token_type != lexer.C && token_type != lexer.NC && token_type != lexer.SZ && token_type != lexer.SNZ && token_type != lexer.SPL && token_type != lexer.SMI && token_type != lexer.SO && token_type != lexer.SE && token_type != lexer.NC5 && token_type != lexer.NC6 && token_type != lexer.NC7 && token_type != lexer.NC8 && token_type != lexer.NC9 && token_type != lexer.NC10 && token_type != lexer.NC11 && token_type != lexer.NC12 && token_type != lexer.NC13 && token_type != lexer.NC14 && token_type != lexer.MAX && token_type != lexer.NMAX && token_type != lexer.SH32 && token_type != lexer.NSH32 && token_type != lexer.EQ && token_type != lexer.NEQ && token_type != lexer.LTU && token_type != lexer.LEU && token_type != lexer.GTU && token_type != lexer.GEU && token_type != lexer.LTS && token_type != lexer.LES && token_type != lexer.GTS && token_type != lexer.GES && token_type != lexer.XZ && token_type != lexer.XNZ && token_type != lexer.XLEU && token_type != lexer.XGTU && token_type != lexer.XLES && token_type != lexer.XGTS && token_type != lexer.SMALL && token_type != lexer.LARGE { err := errors.New("token type is not a condition") panic(err) } this.token = token } func (this *ConditionExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/ddci_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type DdciOpCodeExpr struct { token *lexer.Token } func (this *DdciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.MOVD && token_type != lexer.SWAPD { err := errors.New("token type is not a DDCI op code") panic(err) } this.token = token } func (this *DdciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/dma_rri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type DmaRriOpCodeExpr struct { token *lexer.Token } func (this *DmaRriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LDMA && token_type != lexer.LDMAI && token_type != lexer.SDMA { err := errors.New("token type is not a DMA_RRI op code") panic(err) } this.token = token } func (this *DmaRriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/drdici_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type DrdiciOpCodeExpr struct { token *lexer.Token } func (this *DrdiciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.DIV_STEP && token_type != lexer.MUL_STEP { err := errors.New("token type is not a DRDICI op code") panic(err) } this.token = token } func (this *DrdiciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/endian_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type EndianExpr struct { token *lexer.Token } func (this *EndianExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LITTLE && token_type != lexer.BIG { err := errors.New("token type is not an endian") panic(err) } this.token = token } func (this *EndianExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/expr.go ================================================ package expr import ( "uPIMulator/src/linker/lexer" ) type ExprType int const ( CI_OP_CODE ExprType = iota DDCI_OP_CODE DMA_RRI_OP_CODE DRDICI_OP_CODE I_OP_CODE JUMP_OP_CODE LOAD_OP_CODE R_OP_CODE RICI_OP_CODE RR_OP_CODE RRI_OP_CODE RRRI_OP_CODE STORE_OP_CODE SUFFIX CONDITION ENDIAN SECTION_NAME SECTION_TYPE SYMBOL_TYPE NEGATIVE_NUMBER PRIMARY BINARY_ADD BINARY_SUB PROGRAM_COUNTER SRC_REG ) type Expr struct { expr_type ExprType ci_op_code_expr *CiOpCodeExpr ddci_op_code_expr *DdciOpCodeExpr dma_rri_op_code_expr *DmaRriOpCodeExpr drdici_op_code_expr *DrdiciOpCodeExpr i_op_code_expr *IOpCodeExpr jump_op_code_expr *JumpOpCodeExpr load_op_code_expr *LoadOpCodeExpr r_op_code_expr *ROpCodeExpr rici_op_code_expr *RiciOpCodeExpr rr_op_code_expr *RrOpCodeExpr rri_op_code_expr *RriOpCodeExpr rrri_op_code_expr *RrriOpCodeExpr store_op_code_expr *StoreOpCodeExpr suffix_expr *SuffixExpr condition_expr *ConditionExpr endian_expr *EndianExpr section_name_expr *SectionNameExpr section_type_expr *SectionTypeExpr symbol_type_expr *SymbolTypeExpr negative_number_expr *NegativeNumberExpr primary_expr *PrimaryExpr binary_add_expr *BinaryAddExpr binary_sub_expr *BinarySubExpr program_counter_expr *ProgramCounterExpr src_reg_expr *SrcRegExpr } func (this *Expr) InitCiOpCodeExpr(token *lexer.Token) { this.expr_type = CI_OP_CODE this.ci_op_code_expr = new(CiOpCodeExpr) this.ci_op_code_expr.Init(token) } func (this *Expr) InitDdciOpCodeExpr(token *lexer.Token) { this.expr_type = DDCI_OP_CODE this.ddci_op_code_expr = new(DdciOpCodeExpr) this.ddci_op_code_expr.Init(token) } func (this *Expr) InitDmaRriOpCodeExpr(token *lexer.Token) { this.expr_type = DMA_RRI_OP_CODE this.dma_rri_op_code_expr = new(DmaRriOpCodeExpr) this.dma_rri_op_code_expr.Init(token) } func (this *Expr) InitDrdiciOpCodeExpr(token *lexer.Token) { this.expr_type = DRDICI_OP_CODE this.drdici_op_code_expr = new(DrdiciOpCodeExpr) this.drdici_op_code_expr.Init(token) } func (this *Expr) InitIOpCodeExpr(token *lexer.Token) { this.expr_type = I_OP_CODE this.i_op_code_expr = new(IOpCodeExpr) this.i_op_code_expr.Init(token) } func (this *Expr) InitJumpOpCodeExpr(token *lexer.Token) { this.expr_type = JUMP_OP_CODE this.jump_op_code_expr = new(JumpOpCodeExpr) this.jump_op_code_expr.Init(token) } func (this *Expr) InitLoadOpCodeExpr(token *lexer.Token) { this.expr_type = LOAD_OP_CODE this.load_op_code_expr = new(LoadOpCodeExpr) this.load_op_code_expr.Init(token) } func (this *Expr) InitROpCodeExpr(token *lexer.Token) { this.expr_type = R_OP_CODE this.r_op_code_expr = new(ROpCodeExpr) this.r_op_code_expr.Init(token) } func (this *Expr) InitRiciOpCodeExpr(token *lexer.Token) { this.expr_type = RICI_OP_CODE this.rici_op_code_expr = new(RiciOpCodeExpr) this.rici_op_code_expr.Init(token) } func (this *Expr) InitRrOpCodeExpr(token *lexer.Token) { this.expr_type = RR_OP_CODE this.rr_op_code_expr = new(RrOpCodeExpr) this.rr_op_code_expr.Init(token) } func (this *Expr) InitRriOpCodeExpr(token *lexer.Token) { this.expr_type = RRI_OP_CODE this.rri_op_code_expr = new(RriOpCodeExpr) this.rri_op_code_expr.Init(token) } func (this *Expr) InitRrriOpCodeExpr(token *lexer.Token) { this.expr_type = RRRI_OP_CODE this.rrri_op_code_expr = new(RrriOpCodeExpr) this.rrri_op_code_expr.Init(token) } func (this *Expr) InitStoreOpCodeExpr(token *lexer.Token) { this.expr_type = STORE_OP_CODE this.store_op_code_expr = new(StoreOpCodeExpr) this.store_op_code_expr.Init(token) } func (this *Expr) InitSuffixExpr(token *lexer.Token) { this.expr_type = SUFFIX this.suffix_expr = new(SuffixExpr) this.suffix_expr.Init(token) } func (this *Expr) InitConditionExpr(token *lexer.Token) { this.expr_type = CONDITION this.condition_expr = new(ConditionExpr) this.condition_expr.Init(token) } func (this *Expr) InitEndianExpr(token *lexer.Token) { this.expr_type = ENDIAN this.endian_expr = new(EndianExpr) this.endian_expr.Init(token) } func (this *Expr) InitSectionNameExpr(token *lexer.Token) { this.expr_type = SECTION_NAME this.section_name_expr = new(SectionNameExpr) this.section_name_expr.Init(token) } func (this *Expr) InitSectionTypeExpr(token *lexer.Token) { this.expr_type = SECTION_TYPE this.section_type_expr = new(SectionTypeExpr) this.section_type_expr.Init(token) } func (this *Expr) InitSymbolTypeExpr(token *lexer.Token) { this.expr_type = SYMBOL_TYPE this.symbol_type_expr = new(SymbolTypeExpr) this.symbol_type_expr.Init(token) } func (this *Expr) InitNegativeNumberExpr(token *lexer.Token) { this.expr_type = NEGATIVE_NUMBER this.negative_number_expr = new(NegativeNumberExpr) this.negative_number_expr.Init(token) } func (this *Expr) InitPrimaryExpr(token *lexer.Token) { this.expr_type = PRIMARY this.primary_expr = new(PrimaryExpr) this.primary_expr.Init(token) } func (this *Expr) InitBinaryAddExpr(operand1 *Expr, operand2 *Expr) { this.expr_type = BINARY_ADD this.binary_add_expr = new(BinaryAddExpr) this.binary_add_expr.Init(operand1, operand2) } func (this *Expr) InitBinarySubExpr(operand1 *Expr, operand2 *Expr) { this.expr_type = BINARY_SUB this.binary_sub_expr = new(BinarySubExpr) this.binary_sub_expr.Init(operand1, operand2) } func (this *Expr) InitProgramCounterExpr(expr *Expr) { this.expr_type = PROGRAM_COUNTER this.program_counter_expr = new(ProgramCounterExpr) this.program_counter_expr.Init(expr) } func (this *Expr) InitSrcRegExpr(token *lexer.Token) { this.expr_type = SRC_REG this.src_reg_expr = new(SrcRegExpr) this.src_reg_expr.Init(token) } func (this *Expr) ExprType() ExprType { return this.expr_type } func (this *Expr) CiOpCodeExpr() *CiOpCodeExpr { return this.ci_op_code_expr } func (this *Expr) DdciOpCodeExpr() *DdciOpCodeExpr { return this.ddci_op_code_expr } func (this *Expr) DmaRriOpCodeExpr() *DmaRriOpCodeExpr { return this.dma_rri_op_code_expr } func (this *Expr) DrdiciOpCodeExpr() *DrdiciOpCodeExpr { return this.drdici_op_code_expr } func (this *Expr) IOpCodeExpr() *IOpCodeExpr { return this.i_op_code_expr } func (this *Expr) JumpOpCodeExpr() *JumpOpCodeExpr { return this.jump_op_code_expr } func (this *Expr) LoadOpCodeExpr() *LoadOpCodeExpr { return this.load_op_code_expr } func (this *Expr) ROpCodeExpr() *ROpCodeExpr { return this.r_op_code_expr } func (this *Expr) RiciOpCodeExpr() *RiciOpCodeExpr { return this.rici_op_code_expr } func (this *Expr) RrOpCodeExpr() *RrOpCodeExpr { return this.rr_op_code_expr } func (this *Expr) RriOpCodeExpr() *RriOpCodeExpr { return this.rri_op_code_expr } func (this *Expr) RrriOpCodeExpr() *RrriOpCodeExpr { return this.rrri_op_code_expr } func (this *Expr) StoreOpCodeExpr() *StoreOpCodeExpr { return this.store_op_code_expr } func (this *Expr) SuffixExpr() *SuffixExpr { return this.suffix_expr } func (this *Expr) ConditionExpr() *ConditionExpr { return this.condition_expr } func (this *Expr) EndianExpr() *EndianExpr { return this.endian_expr } func (this *Expr) SectionNameExpr() *SectionNameExpr { return this.section_name_expr } func (this *Expr) SectionTypeExpr() *SectionTypeExpr { return this.section_type_expr } func (this *Expr) SymbolTypeExpr() *SymbolTypeExpr { return this.symbol_type_expr } func (this *Expr) NegativeNumberExpr() *NegativeNumberExpr { return this.negative_number_expr } func (this *Expr) PrimaryExpr() *PrimaryExpr { return this.primary_expr } func (this *Expr) BinaryAddExpr() *BinaryAddExpr { return this.binary_add_expr } func (this *Expr) BinarySubExpr() *BinarySubExpr { return this.binary_sub_expr } func (this *Expr) ProgramCounterExpr() *ProgramCounterExpr { return this.program_counter_expr } func (this *Expr) SrcRegExpr() *SrcRegExpr { return this.src_reg_expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/i_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type IOpCodeExpr struct { token *lexer.Token } func (this *IOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.FAULT && token_type != lexer.BKP { err := errors.New("token type is not an I op code") panic(err) } this.token = token } func (this *IOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/jump_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type JumpOpCodeExpr struct { token *lexer.Token } func (this *JumpOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.JEQ && token_type != lexer.JNEQ && token_type != lexer.JZ && token_type != lexer.JNZ && token_type != lexer.JLTU && token_type != lexer.JGTU && token_type != lexer.JLEU && token_type != lexer.JGEU && token_type != lexer.JLTS && token_type != lexer.JGTS && token_type != lexer.JLES && token_type != lexer.JGES && token_type != lexer.JUMP { err := errors.New("token type is not a jump op code") panic(err) } this.token = token } func (this *JumpOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/load_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type LoadOpCodeExpr struct { token *lexer.Token } func (this *LoadOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LBS && token_type != lexer.LBU && token_type != lexer.LD && token_type != lexer.LHS && token_type != lexer.LHU && token_type != lexer.LW { err := errors.New("token type is not a load op code") panic(err) } this.token = token } func (this *LoadOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/negative_number_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type NegativeNumberExpr struct { token *lexer.Token } func (this *NegativeNumberExpr) Init(token *lexer.Token) { if token.TokenType() != lexer.POSITIVIE_NUMBER { err := errors.New("token type is not positive number") panic(err) } this.token = token } func (this *NegativeNumberExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/primary_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type PrimaryExpr struct { token *lexer.Token } func (this *PrimaryExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.POSITIVIE_NUMBER && token_type != lexer.HEX_NUMBER && token_type != lexer.IDENTIFIER { err := errors.New("token type is not positive number, hex number, nor identifier") panic(err) } this.token = token } func (this *PrimaryExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/program_counter_expr.go ================================================ package expr import ( "errors" ) type ProgramCounterExpr struct { expr *Expr } func (this *ProgramCounterExpr) Init(expr *Expr) { expr_type := expr.ExprType() if expr_type != PRIMARY && expr_type != NEGATIVE_NUMBER && expr_type != BINARY_ADD && expr_type != BINARY_SUB { err := errors.New("expr type is not primary, negative number, binary add, nor binary sub") panic(err) } this.expr = expr } func (this *ProgramCounterExpr) Expr() *Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/r_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type ROpCodeExpr struct { token *lexer.Token } func (this *ROpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.TIME && token_type != lexer.NOP { err := errors.New("token type is not an R op code") panic(err) } this.token = token } func (this *ROpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/rici_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type RiciOpCodeExpr struct { token *lexer.Token } func (this *RiciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ACQUIRE && token_type != lexer.RELEASE && token_type != lexer.BOOT && token_type != lexer.RESUME { err := errors.New("token type is not an RICI op code") panic(err) } this.token = token } func (this *RiciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/rr_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type RrOpCodeExpr struct { token *lexer.Token } func (this *RrOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.CAO && token_type != lexer.CLO && token_type != lexer.CLS && token_type != lexer.CLZ && token_type != lexer.EXTSB && token_type != lexer.EXTSH && token_type != lexer.EXTUB && token_type != lexer.EXTUH && token_type != lexer.SATS && token_type != lexer.TIME_CFG && token_type != lexer.MOVE && token_type != lexer.NEG && token_type != lexer.NOT { err := errors.New("token type is not an RR op code") panic(err) } this.token = token } func (this *RrOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/rri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type RriOpCodeExpr struct { token *lexer.Token } func (this *RriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ADD && token_type != lexer.ADDC && token_type != lexer.AND && token_type != lexer.ANDN && token_type != lexer.ASR && token_type != lexer.CMPB4 && token_type != lexer.LSL && token_type != lexer.LSL1 && token_type != lexer.LSL1X && token_type != lexer.LSLX && token_type != lexer.LSR && token_type != lexer.LSR1 && token_type != lexer.LSR1X && token_type != lexer.LSRX && token_type != lexer.MUL_SH_SH && token_type != lexer.MUL_SH_SL && token_type != lexer.MUL_SH_UH && token_type != lexer.MUL_SH_UL && token_type != lexer.MUL_SL_SH && token_type != lexer.MUL_SL_SL && token_type != lexer.MUL_SL_UH && token_type != lexer.MUL_SL_UL && token_type != lexer.MUL_UH_UH && token_type != lexer.MUL_UH_UL && token_type != lexer.MUL_UL_UH && token_type != lexer.MUL_UL_UL && token_type != lexer.NAND && token_type != lexer.NOR && token_type != lexer.NXOR && token_type != lexer.OR && token_type != lexer.ORN && token_type != lexer.ROL && token_type != lexer.ROR && token_type != lexer.RSUB && token_type != lexer.RSUBC && token_type != lexer.SUB && token_type != lexer.SUBC && token_type != lexer.XOR && token_type != lexer.CALL { err := errors.New("token type is not an RRI op code") panic(err) } this.token = token } func (this *RriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/rrri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type RrriOpCodeExpr struct { token *lexer.Token } func (this *RrriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LSL_ADD && token_type != lexer.LSL_SUB && token_type != lexer.LSR_ADD && token_type != lexer.ROL_ADD { err := errors.New("token type is not an RRRI op code") panic(err) } this.token = token } func (this *RrriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/section_name_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type SectionNameExpr struct { token *lexer.Token } func (this *SectionNameExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ATOMIC && token_type != lexer.BSS && token_type != lexer.DATA && token_type != lexer.DEBUG_ABBREV && token_type != lexer.DEBUG_FRAME && token_type != lexer.DEBUG_INFO && token_type != lexer.DEBUG_LINE && token_type != lexer.DEBUG_LOC && token_type != lexer.DEBUG_RANGES && token_type != lexer.DEBUG_STR && token_type != lexer.DPU_HOST && token_type != lexer.MRAM && token_type != lexer.RODATA && token_type != lexer.STACK_SIZES && token_type != lexer.TEXT { err := errors.New("token type is not a section name") panic(err) } this.token = token } func (this *SectionNameExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/section_type_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type SectionTypeExpr struct { token *lexer.Token } func (this *SectionTypeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.PROGBITS && token_type != lexer.NOBITS { err := errors.New("token type is not a section type") panic(err) } this.token = token } func (this *SectionTypeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/src_reg_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type SrcRegExpr struct { token *lexer.Token } func (this *SrcRegExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.GP_REG && token_type != lexer.ZERO_REG && token_type != lexer.ONE && token_type != lexer.ID && token_type != lexer.ID2 && token_type != lexer.ID4 && token_type != lexer.ID8 && token_type != lexer.LNEG && token_type != lexer.MNEG { err := errors.New("token type is not a src reg") panic(err) } this.token = token } func (this *SrcRegExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/store_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type StoreOpCodeExpr struct { token *lexer.Token } func (this *StoreOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.SB && token_type != lexer.SB_ID && token_type != lexer.SD && token_type != lexer.SD_ID && token_type != lexer.SH && token_type != lexer.SH_ID && token_type != lexer.SW && token_type != lexer.SW_ID { err := errors.New("token type is not a store op code") panic(err) } this.token = token } func (this *StoreOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/suffix_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type SuffixExpr struct { token *lexer.Token } func (this *SuffixExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.S && token_type != lexer.U { err := errors.New("token type is not a suffix") panic(err) } this.token = token } func (this *SuffixExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/expr/symbol_type.go ================================================ package expr import ( "errors" "uPIMulator/src/linker/lexer" ) type SymbolTypeExpr struct { token *lexer.Token } func (this *SymbolTypeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.FUNCTION && token_type != lexer.OBJECT { err := errors.New("token type is not a symbol type") panic(err) } this.token = token } func (this *SymbolTypeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/parser.go ================================================ package parser import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" ) type Parser struct { stack *Stack table *Table } func (this *Parser) Init() { this.stack = new(Stack) this.stack.Init() this.table = new(Table) this.table.Init(this.stack) this.RegisterAccessExpr() this.RegisterConcatExpr() this.RegisterBinaryAddExpr() this.RegisterBinarySubExpr() this.RegisterCiOpCodeExpr() this.RegisterConditionExpr() this.RegisterDdciOpCodeExpr() this.RegisterDmaRriOpCodeExpr() this.RegisterDrdiciOpCodeExpr() this.RegisterEndianExpr() this.RegisterIOpCodeExpr() this.RegisterJumpOpCodeExpr() this.RegisterLoadOpCodeExpr() this.RegisterNegativeNumberExpr() this.RegisterPrimaryExpr() this.RegisterProgramCounterExpr() this.RegisterROpCodeExpr() this.RegisterRiciOpCodeExpr() this.RegisterRrOpCodeExpr() this.RegisterRriOpCodeExpr() this.RegisterRrriOpCodeExpr() this.RegisterSectionNameExpr() this.RegisterSectionTypeExpr() this.RegisterSrcRegExpr() this.RegisterStoreOpCodeExpr() this.RegisterSuffixExpr() this.RegisterSymbolTypeExpr() this.RegisterAddrsigStmt() this.RegisterAddrsigSymStmt() this.RegisterAsciiStmt() this.RegisterAscizStmt() this.RegisterByteStmt() this.RegisterCfiDefCfaOffsetStmt() this.RegisterCfiEndprocStmt() this.RegisterCfiOffsetStmt() this.RegisterCfiSectionsStmt() this.RegisterCfiStartprocStmt() this.RegisterFileNumberStmt() this.RegisterFileStringStmt() this.RegisterGlobalStmt() this.RegisterLocIsStmtStmt() this.RegisterLocNumberStmt() this.RegisterLocPrologueEndStmt() this.RegisterLongProgramCounterStmt() this.RegisterLongSectionNameStmt() this.RegisterP2AlignStmt() this.RegisterQuadStmt() this.RegisterSectionIdentifierNumberStmt() this.RegisterSectionIdentifierStmt() this.RegisterSectionStackSizesStmt() this.RegisterSectionStringNumberStmt() this.RegisterSectionStringStmt() this.RegisterSetStmt() this.RegisterShortStmt() this.RegisterSizeStmt() this.RegisterTextStmt() this.RegisterTypeStmt() this.RegisterWeakStmt() this.RegisterZeroDoubleNumberStmt() this.RegisterZeroSingleNumberStmt() this.RegisterCiStmt() this.RegisterDdciStmt() this.RegisterDmaRriStmt() this.RegisterDrdiciStmt() this.RegisterEdriStmt() this.RegisterEriiStmt() this.RegisterErirStmt() this.RegisterErriStmt() this.RegisterIStmt() this.RegisterRciStmt() this.RegisterRiciStmt() this.RegisterRirciStmt() this.RegisterRircStmt() this.RegisterRirStmt() this.RegisterRrciStmt() this.RegisterRrcStmt() this.RegisterRriciStmt() this.RegisterRricStmt() this.RegisterRriStmt() this.RegisterRrrciStmt() this.RegisterRrrcStmt() this.RegisterRrriciStmt() this.RegisterRrriStmt() this.RegisterRrrStmt() this.RegisterRrStmt() this.RegisterRStmt() this.RegisterSErriStmt() this.RegisterSRciStmt() this.RegisterSRirciStmt() this.RegisterSRrciStmt() this.RegisterSRrcStmt() this.RegisterSRriciStmt() this.RegisterSRricStmt() this.RegisterSRriStmt() this.RegisterSRrrciStmt() this.RegisterSRrrcStmt() this.RegisterSRrriciStmt() this.RegisterSRrriStmt() this.RegisterSRrrStmt() this.RegisterSRrStmt() this.RegisterSRStmt() this.RegisterNopStmt() this.RegisterBkpStmt() this.RegisterBootRiStmt() this.RegisterCallRiStmt() this.RegisterCallRrStmt() this.RegisterDivStepDrdiStmt() this.RegisterJeqRiiStmt() this.RegisterJeqRriStmt() this.RegisterJnzRiStmt() this.RegisterJumpIStmt() this.RegisterJumpRStmt() this.RegisterLbsRriStmt() this.RegisterLbsSRriStmt() this.RegisterLdDriStmt() this.RegisterMovdDdStmt() this.RegisterMoveRiciStmt() this.RegisterMoveRiStmt() this.RegisterMoveSRiciStmt() this.RegisterMoveSRiStmt() this.RegisterSbIdRiiStmt() this.RegisterSbIdRiStmt() this.RegisterSbRirStmt() this.RegisterSdRidStmt() this.RegisterStopStmt() this.RegisterTimeCfgRStmt() this.RegisterLabelStmt() } func (this *Parser) Parse(token_stream *lexer.TokenStream) *Ast { for pos := 0; pos < token_stream.Size(); pos++ { token := token_stream.Get(pos) this.ReduceExpr(token) if token.TokenType() != lexer.NEW_LINE { stack_item := new(StackItem) stack_item.InitToken(token) this.stack.Push(stack_item) } else { this.ReduceStmt(token) if !this.stack.AreStmts() { err := errors.New("stack are not stmts") panic(err) } } } if !this.stack.CanAccept() { err := errors.New("stack cannot be accepted") panic(err) } return this.stack.Accept() } func (this *Parser) ReduceExpr(token *lexer.Token) { for { reducible_expr_rule, stack_items := this.table.FindReducibleExprRule(token) if reducible_expr_rule != nil { stack_item := reducible_expr_rule.Reduce(stack_items, token) this.stack.Pop(len(stack_items)) this.stack.Push(stack_item) } else { break } } } func (this *Parser) ReduceStmt(token *lexer.Token) { for { reducible_stmt_rule, stack_items := this.table.FindReducibleStmtRule(token) if reducible_stmt_rule != nil { stack_item := reducible_stmt_rule.Reduce(stack_items, token) this.stack.Pop(len(stack_items)) this.stack.Push(stack_item) } else { break } } } func (this *Parser) RegisterAccessExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.IDENTIFIER && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token1 := stack_items[0].Token() token2 := stack_items[1].Token() attribute := token1.Attribute() + token2.Attribute() token := new(lexer.Token) token.Init(lexer.IDENTIFIER, attribute) stack_item := new(StackItem) stack_item.InitToken(token) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterConcatExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.NEGATIVE_NUMBER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[1].Expr() negative_number_expr := operand2.NegativeNumberExpr() token := negative_number_expr.Token() primary_expr := new(expr.Expr) primary_expr.InitPrimaryExpr(token) binary_sub_expr := new(expr.Expr) binary_sub_expr.InitBinarySubExpr(operand1, primary_expr) stack_item := new(StackItem) stack_item.InitExpr(binary_sub_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterBinaryAddExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PLUS && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PRIMARY { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[2].Expr() binary_add_expr := new(expr.Expr) binary_add_expr.InitBinaryAddExpr(operand1, operand2) stack_item := new(StackItem) stack_item.InitExpr(binary_add_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterBinarySubExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MINUS && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PRIMARY { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[2].Expr() binary_sub_expr := new(expr.Expr) binary_sub_expr.InitBinarySubExpr(operand1, operand2) stack_item := new(StackItem) stack_item.InitExpr(binary_sub_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterCiOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.STOP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() ci_op_code_expr := new(expr.Expr) ci_op_code_expr.InitCiOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(ci_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDdciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.MOVD || token_type == lexer.SWAPD { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() ddci_op_code_expr := new(expr.Expr) ddci_op_code_expr.InitDdciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(ddci_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDmaRriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LDMA || token_type == lexer.LDMAI || token_type == lexer.SDMA { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() dma_rri_op_code_expr := new(expr.Expr) dma_rri_op_code_expr.InitDmaRriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(dma_rri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDrdiciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.DIV_STEP || token_type == lexer.MUL_STEP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() drdici_op_code_expr := new(expr.Expr) drdici_op_code_expr.InitDrdiciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(drdici_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterConditionExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.TRUE || token_type == lexer.FALSE || token_type == lexer.Z || token_type == lexer.NZ || token_type == lexer.E || token_type == lexer.O || token_type == lexer.PL || token_type == lexer.MI || token_type == lexer.OV || token_type == lexer.NOV || token_type == lexer.C || token_type == lexer.NC || token_type == lexer.SZ || token_type == lexer.SNZ || token_type == lexer.SPL || token_type == lexer.SMI || token_type == lexer.SO || token_type == lexer.SE || token_type == lexer.NC5 || token_type == lexer.NC5 || token_type == lexer.NC6 || token_type == lexer.NC7 || token_type == lexer.NC8 || token_type == lexer.NC9 || token_type == lexer.NC10 || token_type == lexer.NC11 || token_type == lexer.NC12 || token_type == lexer.NC13 || token_type == lexer.NC14 || token_type == lexer.MAX || token_type == lexer.NMAX || token_type == lexer.SH32 || token_type == lexer.NSH32 || token_type == lexer.EQ || token_type == lexer.NEQ || token_type == lexer.LTU || token_type == lexer.LEU || token_type == lexer.GTU || token_type == lexer.GEU || token_type == lexer.LTS || token_type == lexer.LES || token_type == lexer.GTS || token_type == lexer.GES || token_type == lexer.XZ || token_type == lexer.XNZ || token_type == lexer.XLEU || token_type == lexer.XGTU || token_type == lexer.XLES || token_type == lexer.XGTS || token_type == lexer.SMALL || token_type == lexer.LARGE { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() condition_expr := new(expr.Expr) condition_expr.InitConditionExpr(token) stack_item := new(StackItem) stack_item.InitExpr(condition_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterEndianExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LITTLE || token_type == lexer.BIG { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() endian_expr := new(expr.Expr) endian_expr.InitEndianExpr(token) stack_item := new(StackItem) stack_item.InitExpr(endian_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterIOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.FAULT || token_type == lexer.BKP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() i_op_code_expr := new(expr.Expr) i_op_code_expr.InitIOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(i_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterJumpOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.JEQ || token_type == lexer.JNEQ || token_type == lexer.JZ || token_type == lexer.JNZ || token_type == lexer.JLTU || token_type == lexer.JGTU || token_type == lexer.JLEU || token_type == lexer.JGEU || token_type == lexer.JLTS || token_type == lexer.JGTS || token_type == lexer.JLES || token_type == lexer.JGES || token_type == lexer.JUMP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() jump_op_code_expr := new(expr.Expr) jump_op_code_expr.InitJumpOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(jump_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterLoadOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LBS || token_type == lexer.LBU || token_type == lexer.LD || token_type == lexer.LHS || token_type == lexer.LHU || token_type == lexer.LW { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() load_op_code_expr := new(expr.Expr) load_op_code_expr.InitLoadOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(load_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterNegativeNumberExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.MINUS && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.POSITIVIE_NUMBER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() negativer_number_expr := new(expr.Expr) negativer_number_expr.InitNegativeNumberExpr(token) stack_item := new(StackItem) stack_item.InitExpr(negativer_number_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterPrimaryExpr() { precedence := map[lexer.TokenType]bool{lexer.IDENTIFIER: true} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.POSITIVIE_NUMBER || token_type == lexer.HEX_NUMBER || token_type == lexer.IDENTIFIER { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.Expr) primary_expr.InitPrimaryExpr(token) stack_item := new(StackItem) stack_item.InitExpr(primary_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterProgramCounterExpr() { precedence := map[lexer.TokenType]bool{lexer.PLUS: true, lexer.MINUS: true} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR { expr_type := stack_items[0].Expr().ExprType() if expr_type == expr.PRIMARY || expr_type == expr.NEGATIVE_NUMBER || expr_type == expr.BINARY_ADD || expr_type == expr.BINARY_SUB { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[0].Expr() program_counter_expr := new(expr.Expr) program_counter_expr.InitProgramCounterExpr(expr_) stack_item := new(StackItem) stack_item.InitExpr(program_counter_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterROpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.TIME || token_type == lexer.NOP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() r_op_code_expr := new(expr.Expr) r_op_code_expr.InitROpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(r_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRiciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ACQUIRE || token_type == lexer.RELEASE || token_type == lexer.BOOT || token_type == lexer.RESUME { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rici_op_code_expr := new(expr.Expr) rici_op_code_expr.InitRiciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rici_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRrOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.CAO || token_type == lexer.CLO || token_type == lexer.CLS || token_type == lexer.CLZ || token_type == lexer.EXTSB || token_type == lexer.EXTSH || token_type == lexer.EXTUB || token_type == lexer.EXTUH || token_type == lexer.SATS || token_type == lexer.TIME_CFG || token_type == lexer.MOVE || token_type == lexer.NEG || token_type == lexer.NOT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rr_op_code_expr := new(expr.Expr) rr_op_code_expr.InitRrOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rr_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ADD || token_type == lexer.ADDC || token_type == lexer.AND || token_type == lexer.ANDN || token_type == lexer.ASR || token_type == lexer.CMPB4 || token_type == lexer.LSL || token_type == lexer.LSL1 || token_type == lexer.LSL1X || token_type == lexer.LSLX || token_type == lexer.LSR || token_type == lexer.LSR1 || token_type == lexer.LSR1X || token_type == lexer.LSRX || token_type == lexer.MUL_SH_SH || token_type == lexer.MUL_SH_SL || token_type == lexer.MUL_SH_UH || token_type == lexer.MUL_SH_UL || token_type == lexer.MUL_SL_SH || token_type == lexer.MUL_SL_SL || token_type == lexer.MUL_SL_UH || token_type == lexer.MUL_SL_UL || token_type == lexer.MUL_UH_UH || token_type == lexer.MUL_UH_UL || token_type == lexer.MUL_UL_UH || token_type == lexer.MUL_UL_UL || token_type == lexer.NAND || token_type == lexer.NOR || token_type == lexer.NXOR || token_type == lexer.OR || token_type == lexer.ORN || token_type == lexer.ROL || token_type == lexer.ROR || token_type == lexer.RSUB || token_type == lexer.RSUBC || token_type == lexer.SUB || token_type == lexer.SUBC || token_type == lexer.XOR || token_type == lexer.CALL { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rri_op_code_expr := new(expr.Expr) rri_op_code_expr.InitRriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRrriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LSL_ADD || token_type == lexer.LSL_SUB || token_type == lexer.LSR_ADD || token_type == lexer.ROL_ADD { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rrri_op_code_expr := new(expr.Expr) rrri_op_code_expr.InitRrriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rrri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterStoreOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.SB || token_type == lexer.SB_ID || token_type == lexer.SD || token_type == lexer.SD_ID || token_type == lexer.SH || token_type == lexer.SH_ID || token_type == lexer.SW || token_type == lexer.SW_ID { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() store_op_code_expr := new(expr.Expr) store_op_code_expr.InitStoreOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(store_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSuffixExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.S || token_type == lexer.U { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() suffix_expr := new(expr.Expr) suffix_expr.InitSuffixExpr(token) stack_item := new(StackItem) stack_item.InitExpr(suffix_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSectionNameExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ATOMIC || token_type == lexer.BSS || token_type == lexer.DATA || token_type == lexer.DEBUG_ABBREV || token_type == lexer.DEBUG_FRAME || token_type == lexer.DEBUG_INFO || token_type == lexer.DEBUG_LINE || token_type == lexer.DEBUG_LOC || token_type == lexer.DEBUG_RANGES || token_type == lexer.DEBUG_STR || token_type == lexer.DPU_HOST || token_type == lexer.MRAM || token_type == lexer.RODATA || token_type == lexer.STACK_SIZES || token_type == lexer.TEXT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() section_name_expr := new(expr.Expr) section_name_expr.InitSectionNameExpr(token) stack_item := new(StackItem) stack_item.InitExpr(section_name_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSectionTypeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.PROGBITS || token_type == lexer.NOBITS { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() section_type_expr := new(expr.Expr) section_type_expr.InitSectionTypeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(section_type_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSrcRegExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.GP_REG || token_type == lexer.ZERO_REG || token_type == lexer.ONE || token_type == lexer.ID || token_type == lexer.ID2 || token_type == lexer.ID4 || token_type == lexer.ID8 || token_type == lexer.LNEG || token_type == lexer.MNEG { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() src_reg_expr := new(expr.Expr) src_reg_expr.InitSrcRegExpr(token) stack_item := new(StackItem) stack_item.InitExpr(src_reg_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSymbolTypeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.FUNCTION || token_type == lexer.OBJECT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() symbol_type_expr := new(expr.Expr) symbol_type_expr.InitSymbolTypeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(symbol_type_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterAddrsigStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ADDRSIG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { addrsig_stmt := new(stmt.Stmt) addrsig_stmt.InitAddrsigStmt() stack_item := new(StackItem) stack_item.InitStmt(addrsig_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAddrsigSymStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ADDRSIG_SYM && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() addrsig_sym_stmt := new(stmt.Stmt) addrsig_sym_stmt.InitAddrsigSymStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(addrsig_sym_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAsciiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ASCII && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() ascii_stmt := new(stmt.Stmt) ascii_stmt.InitAsciiStmt(token) stack_item := new(StackItem) stack_item.InitStmt(ascii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAscizStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ASCIZ && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() asciz_stmt := new(stmt.Stmt) asciz_stmt.InitAscizStmt(token) stack_item := new(StackItem) stack_item.InitStmt(asciz_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterByteStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.BYTE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() byte_stmt := new(stmt.Stmt) byte_stmt.InitByteStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(byte_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiDefCfaOffsetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_DEF_CFA_OFFSET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() cfi_def_cfa_offset_stmt := new(stmt.Stmt) cfi_def_cfa_offset_stmt.InitCfiDefCfaOffsetStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(cfi_def_cfa_offset_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiEndprocStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_ENDPROC { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { cfi_endproc_stmt := new(stmt.Stmt) cfi_endproc_stmt.InitCfiEndprocStmt() stack_item := new(StackItem) stack_item.InitStmt(cfi_endproc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiOffsetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_OFFSET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() cfi_offset_stmt := new(stmt.Stmt) cfi_offset_stmt.InitCfiOffsetStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(cfi_offset_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiSectionsStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_SECTIONS && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() cfi_sections_stmt := new(stmt.Stmt) cfi_sections_stmt.InitCfiSectionsStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(cfi_sections_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiStartprocStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_STARTPROC { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { cfi_startproc_stmt := new(stmt.Stmt) cfi_startproc_stmt.InitCfiStartprocStmt() stack_item := new(StackItem) stack_item.InitStmt(cfi_startproc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterFileNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.FILE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.STRING && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() token1 := stack_items[2].Token() token2 := stack_items[3].Token() file_number_stmt := new(stmt.Stmt) file_number_stmt.InitFileNumberStmt(expr_, token1, token2) stack_item := new(StackItem) stack_item.InitStmt(file_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterFileStringStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.FILE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() file_string_stmt := new(stmt.Stmt) file_string_stmt.InitFileStringStmt(token) stack_item := new(StackItem) stack_item.InitStmt(file_string_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterGlobalStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.GLOBL && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() global_stmt := new(stmt.Stmt) global_stmt.InitGlobalStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(global_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocIsStmtStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.IS_STMT && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() expr4 := stack_items[5].Expr() loc_is_stmt_stmt := new(stmt.Stmt) loc_is_stmt_stmt.InitLocIsStmtStmt(expr1, expr2, expr3, expr4) stack_item := new(StackItem) stack_item.InitStmt(loc_is_stmt_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() loc_number_stmt := new(stmt.Stmt) loc_number_stmt.InitLocNumberStmt(expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(loc_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocPrologueEndStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.PROLOGUE_END { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() loc_prologue_end_stmt := new(stmt.Stmt) loc_prologue_end_stmt.InitLocPrologueEndStmt(expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(loc_prologue_end_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLongProgramCounterStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LONG && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() long_program_counter_stmt := new(stmt.Stmt) long_program_counter_stmt.InitLongProgramCounterStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(long_program_counter_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLongSectionNameStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LONG && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() long_section_name_stmt := new(stmt.Stmt) long_section_name_stmt.InitLongSectionNameStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(long_section_name_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterP2AlignStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.P2ALIGN && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() p2align_stmt := new(stmt.Stmt) p2align_stmt.InitP2AlignStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(p2align_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterQuadStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.QUAD && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() quad_stmt := new(stmt.Stmt) quad_stmt.InitQuadStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(quad_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionIdentifierNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.STRING && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SECTION_TYPE && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() token := stack_items[4].Token() expr3 := stack_items[6].Expr() expr4 := stack_items[8].Expr() section_identifier_number_stmt := new(stmt.Stmt) section_identifier_number_stmt.InitSectionIdentifierNumberStmt( expr1, expr2, token, expr3, expr4, ) stack_item := new(StackItem) stack_item.InitStmt(section_identifier_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionIdentifierStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.STRING && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SECTION_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() token := stack_items[4].Token() expr3 := stack_items[6].Expr() section_identifier_stmt := new(stmt.Stmt) section_identifier_stmt.InitSectionIdentifierStmt(expr1, expr2, token, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_identifier_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStackSizesStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.SECTION_NAME && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[3].Token() expr1 := stack_items[5].Expr() expr2 := stack_items[7].Expr() expr3 := stack_items[8].Expr() section_stack_sizes_stmt := new(stmt.Stmt) section_stack_sizes_stmt.InitSectionStackSizesStmt(token, expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_stack_sizes_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStringNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() token := stack_items[3].Token() expr2 := stack_items[5].Expr() expr3 := stack_items[7].Expr() section_string_number_stmt := new(stmt.Stmt) section_string_number_stmt.InitSectionStringNumberStmt(expr1, token, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_string_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStringStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() token := stack_items[3].Token() expr2 := stack_items[5].Expr() section_string_stmt := new(stmt.Stmt) section_string_stmt.InitSectionStringStmt(expr1, token, expr2) stack_item := new(StackItem) stack_item.InitStmt(section_string_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() set_stmt := new(stmt.Stmt) set_stmt.InitSetStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(set_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterShortStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SHORT && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() short_stmt := new(stmt.Stmt) short_stmt.InitShortStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(short_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSizeStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SIZE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() size_stmt := new(stmt.Stmt) size_stmt.InitSizeStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(size_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTextStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.SECTION_NAME { expr_ := stack_items[0].Expr() if expr_.SectionNameExpr().Token().TokenType() == lexer.TEXT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { text_stmt := new(stmt.Stmt) text_stmt.InitTextStmt() stack_item := new(StackItem) stack_item.InitStmt(text_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTypeStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.TYPE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SYMBOL_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() type_stmt := new(stmt.Stmt) type_stmt.InitTypeStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(type_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterWeakStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.WEAK && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() weak_stmt := new(stmt.Stmt) weak_stmt.InitWeakStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(weak_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterZeroDoubleNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ZERO_DIRECTIVE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() zero_double_number_stmt := new(stmt.Stmt) zero_double_number_stmt.InitZeroDoubleNumberStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(zero_double_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterZeroSingleNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ZERO_DIRECTIVE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() zero_single_number_stmt := new(stmt.Stmt) zero_single_number_stmt.InitZeroSingleNumberStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(zero_single_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.CI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.CONDITION && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() condition := stack_items[1].Expr() pc := stack_items[3].Expr() ci_stmt := new(stmt.Stmt) ci_stmt.InitCiStmt(op_code, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(ci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDdciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DDCI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() db := stack_items[3].Token() condition := stack_items[5].Expr() pc := stack_items[7].Expr() ddci_stmt := new(stmt.Stmt) ddci_stmt.InitDdciStmt(op_code, dc, db, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(ddci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDmaRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DMA_RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() rb := stack_items[3].Expr() pc := stack_items[5].Expr() dma_rri_stmt := new(stmt.Stmt) dma_rri_stmt.InitDmaRriStmt(op_code, ra, rb, pc) stack_item := new(StackItem) stack_item.InitStmt(dma_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDrdiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 12 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DRDICI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.CONDITION && stack_items[10].StackItemType() == TOKEN && stack_items[10].Token().TokenType() == lexer.COMMA && stack_items[11].StackItemType() == EXPR && stack_items[11].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() db := stack_items[5].Token() imm := stack_items[7].Expr() condition := stack_items[9].Expr() pc := stack_items[11].Expr() drdici_stmt := new(stmt.Stmt) drdici_stmt.InitDrdiciStmt(op_code, dc, ra, db, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(drdici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEdriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() dc := stack_items[3].Token() ra := stack_items[5].Expr() off := stack_items[7].Expr() edri_stmt := new(stmt.Stmt) edri_stmt.InitEdriStmt(op_code, endian, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(edri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEridStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() db := stack_items[7].Token() edri_stmt := new(stmt.Stmt) edri_stmt.InitEridStmt(op_code, endian, ra, off, db) stack_item := new(StackItem) stack_item.InitStmt(edri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEriiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() imm := stack_items[7].Expr() erii_stmt := new(stmt.Stmt) erii_stmt.InitEriiStmt(op_code, endian, ra, off, imm) stack_item := new(StackItem) stack_item.InitStmt(erii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterErirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() rb := stack_items[7].Expr() erir_stmt := new(stmt.Stmt) erir_stmt.InitErirStmt(op_code, endian, ra, off, rb) stack_item := new(StackItem) stack_item.InitStmt(erir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterErriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() rc := stack_items[3].Expr() ra := stack_items[5].Expr() off := stack_items[7].Expr() erri_stmt := new(stmt.Stmt) erri_stmt.InitErriStmt(op_code, endian, rc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(erri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterIStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.I_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() imm := stack_items[1].Expr() i_stmt := new(stmt.Stmt) i_stmt.InitIStmt(op_code, imm) stack_item := new(StackItem) stack_item.InitStmt(i_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.CONDITION && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() condition := stack_items[3].Expr() pc := stack_items[5].Expr() rci_stmt := new(stmt.Stmt) rci_stmt.InitRciStmt(op_code, rc, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RICI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() rici_stmt := new(stmt.Stmt) rici_stmt.InitRiciStmt(op_code, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRirciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rirci_stmt := new(stmt.Stmt) rirci_stmt.InitRirciStmt(op_code, rc, imm, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rirci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRircStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() condition := stack_items[7].Expr() rirc_stmt := new(stmt.Stmt) rirc_stmt.InitRircStmt(op_code, rc, imm, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(rirc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() rir_stmt := new(stmt.Stmt) rir_stmt.InitRirStmt(op_code, rc, imm, ra) stack_item := new(StackItem) stack_item.InitStmt(rir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() rrci_stmt := new(stmt.Stmt) rrci_stmt.InitRrciStmt(op_code, rc, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() condition := stack_items[5].Expr() rrc_stmt := new(stmt.Stmt) rrc_stmt.InitRrcStmt(op_code, rc, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(rrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rrici_stmt := new(stmt.Stmt) rrici_stmt.InitRriciStmt(op_code, rc, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRricStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() condition := stack_items[7].Expr() rric_stmt := new(stmt.Stmt) rric_stmt.InitRricStmt(op_code, rc, ra, imm, condition) stack_item := new(StackItem) stack_item.InitStmt(rric_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() rri_stmt := new(stmt.Stmt) rri_stmt.InitRriStmt(op_code, rc, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rrrci_stmt := new(stmt.Stmt) rrrci_stmt.InitRrrciStmt(op_code, rc, ra, rb, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() condition := stack_items[7].Expr() rrrc_stmt := new(stmt.Stmt) rrrc_stmt.InitRrrcStmt(op_code, rc, ra, rb, condition) stack_item := new(StackItem) stack_item.InitStmt(rrrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 12 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.CONDITION && stack_items[10].StackItemType() == TOKEN && stack_items[10].Token().TokenType() == lexer.COMMA && stack_items[11].StackItemType() == EXPR && stack_items[11].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() imm := stack_items[7].Expr() condition := stack_items[9].Expr() pc := stack_items[11].Expr() rrrici_stmt := new(stmt.Stmt) rrrici_stmt.InitRrriciStmt(op_code, rc, ra, rb, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() imm := stack_items[7].Expr() rrri_stmt := new(stmt.Stmt) rrri_stmt.InitRrriStmt(op_code, rc, ra, rb, imm) stack_item := new(StackItem) stack_item.InitStmt(rrri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() rrr_stmt := new(stmt.Stmt) rrr_stmt.InitRrrStmt(op_code, rc, ra, rb) stack_item := new(StackItem) stack_item.InitStmt(rrr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rr_stmt := new(stmt.Stmt) rr_stmt.InitRrStmt(op_code, rc, ra) stack_item := new(StackItem) stack_item.InitStmt(rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() r_stmt := new(stmt.Stmt) r_stmt.InitRStmt(op_code, rc) stack_item := new(StackItem) stack_item.InitStmt(r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSErriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.ENDIAN && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.PAIR_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() endian := stack_items[2].Expr() dc := stack_items[4].Token() ra := stack_items[6].Expr() off := stack_items[8].Expr() s_erri_stmt := new(stmt.Stmt) s_erri_stmt.InitSErriStmt(op_code, suffix, endian, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(s_erri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.CONDITION && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() condition := stack_items[4].Expr() pc := stack_items[6].Expr() s_rci_stmt := new(stmt.Stmt) s_rci_stmt.InitSRciStmt(op_code, suffix, dc, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRirciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() ra := stack_items[6].Expr() condition := stack_items[8].Expr() pc := stack_items[10].Expr() s_rirci_stmt := new(stmt.Stmt) s_rirci_stmt.InitSRirciStmt(op_code, suffix, dc, imm, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rirci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRircStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() ra := stack_items[6].Expr() condition := stack_items[8].Expr() s_rirc_stmt := new(stmt.Stmt) s_rirc_stmt.InitSRircStmt(op_code, suffix, dc, imm, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rirc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() condition := stack_items[6].Expr() pc := stack_items[8].Expr() s_rrci_stmt := new(stmt.Stmt) s_rrci_stmt.InitSRrciStmt(op_code, suffix, dc, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() condition := stack_items[6].Expr() s_rrc_stmt := new(stmt.Stmt) s_rrc_stmt.InitSRrcStmt(op_code, suffix, dc, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() condition := stack_items[8].Expr() pc := stack_items[10].Expr() s_rrici_stmt := new(stmt.Stmt) s_rrici_stmt.InitSRriciStmt(op_code, suffix, dc, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRricStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() condition := stack_items[8].Expr() s_rric_stmt := new(stmt.Stmt) s_rric_stmt.InitSRricStmt(op_code, suffix, dc, ra, imm, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rric_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() s_rri_stmt := new(stmt.Stmt) s_rri_stmt.InitSRriStmt(op_code, suffix, dc, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(s_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() condition := stack_items[7].Expr() pc := stack_items[10].Expr() s_rrrci_stmt := new(stmt.Stmt) s_rrrci_stmt.InitSRrrciStmt(op_code, suffix, dc, ra, rb, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() condition := stack_items[7].Expr() s_rrrc_stmt := new(stmt.Stmt) s_rrrc_stmt.InitSRrrcStmt(op_code, suffix, dc, ra, rb, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rrrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 13 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.CONDITION && stack_items[11].StackItemType() == TOKEN && stack_items[11].Token().TokenType() == lexer.COMMA && stack_items[12].StackItemType() == EXPR && stack_items[12].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() imm := stack_items[8].Expr() condition := stack_items[10].Expr() pc := stack_items[12].Expr() s_rrrici_stmt := new(stmt.Stmt) s_rrrici_stmt.InitSRrriciStmt(op_code, suffix, dc, ra, rb, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() imm := stack_items[8].Expr() s_rrri_stmt := new(stmt.Stmt) s_rrri_stmt.InitSRrriStmt(op_code, suffix, dc, ra, rb, imm) stack_item := new(StackItem) stack_item.InitStmt(s_rrri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() s_rrr_stmt := new(stmt.Stmt) s_rrr_stmt.InitSRrrStmt(op_code, suffix, dc, ra, rb) stack_item := new(StackItem) stack_item.InitStmt(s_rrr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() s_rr_stmt := new(stmt.Stmt) s_rr_stmt.InitSRrStmt(op_code, suffix, dc, ra) stack_item := new(StackItem) stack_item.InitStmt(s_rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() s_r_stmt := new(stmt.Stmt) s_r_stmt.InitSRStmt(op_code, suffix, dc) stack_item := new(StackItem) stack_item.InitStmt(s_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterNopStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() if op_code.ROpCodeExpr().Token().TokenType() != lexer.NOP { err := errors.New("op code is not NOP") panic(err) } nop_stmt := new(stmt.Stmt) nop_stmt.InitNopStmt(op_code) stack_item := new(StackItem) stack_item.InitStmt(nop_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterBkpStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.I_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() if op_code.IOpCodeExpr().Token().TokenType() != lexer.BKP { err := errors.New("op code is not BKP") panic(err) } bkp_stmt := new(stmt.Stmt) bkp_stmt.InitBkpStmt() stack_item := new(StackItem) stack_item.InitStmt(bkp_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterBootRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RICI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RiciOpCodeExpr().Token().TokenType() if token_type != lexer.BOOT && token_type != lexer.RESUME { err := errors.New("op code is not BOOT nor RESUME") panic(err) } boot_ri_stmt := new(stmt.Stmt) boot_ri_stmt.InitBootRiStmt(op_code, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(boot_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCallRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RriOpCodeExpr().Token().TokenType() if token_type != lexer.CALL { err := errors.New("op code is not CALL") panic(err) } call_ri_stmt := new(stmt.Stmt) call_ri_stmt.InitCallRiStmt(rc, imm) stack_item := new(StackItem) stack_item.InitStmt(call_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCallRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() token_type := op_code.RriOpCodeExpr().Token().TokenType() if token_type != lexer.CALL { err := errors.New("op code is not CALL") panic(err) } call_rr_stmt := new(stmt.Stmt) call_rr_stmt.InitCallRrStmt(rc, ra) stack_item := new(StackItem) stack_item.InitStmt(call_rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDivStepDrdiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DRDICI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() db := stack_items[5].Token() pc := stack_items[7].Expr() div_step_drdi_stmt := new(stmt.Stmt) div_step_drdi_stmt.InitDivStepDrdiStmt(op_code, dc, ra, db, pc) stack_item := new(StackItem) stack_item.InitStmt(div_step_drdi_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJeqRiiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() pc := stack_items[5].Expr() jeq_rii_stmt := new(stmt.Stmt) jeq_rii_stmt.InitJeqRiiStmt(op_code, ra, imm, pc) stack_item := new(StackItem) stack_item.InitStmt(jeq_rii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJeqRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() rb := stack_items[3].Expr() pc := stack_items[5].Expr() jeq_rri_stmt := new(stmt.Stmt) jeq_rri_stmt.InitJeqRriStmt(op_code, ra, rb, pc) stack_item := new(StackItem) stack_item.InitStmt(jeq_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJnzRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() pc := stack_items[3].Expr() jnz_ri_stmt := new(stmt.Stmt) jnz_ri_stmt.InitJnzRiStmt(op_code, ra, pc) stack_item := new(StackItem) stack_item.InitStmt(jnz_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJumpIStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() pc := stack_items[1].Expr() token_type := op_code.JumpOpCodeExpr().Token().TokenType() if token_type != lexer.JUMP { err := errors.New("op code is not JUMP") panic(err) } jump_i_stmt := new(stmt.Stmt) jump_i_stmt.InitJumpIStmt(pc) stack_item := new(StackItem) stack_item.InitStmt(jump_i_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJumpRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() token_type := op_code.JumpOpCodeExpr().Token().TokenType() if token_type != lexer.JUMP { err := errors.New("op code is not JUMP") panic(err) } jump_r_stmt := new(stmt.Stmt) jump_r_stmt.InitJumpRStmt(ra) stack_item := new(StackItem) stack_item.InitStmt(jump_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLbsRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() lbs_rri_stmt := new(stmt.Stmt) lbs_rri_stmt.InitLbsRriStmt(op_code, rc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(lbs_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLbsSRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() off := stack_items[6].Expr() lbs_s_rri_stmt := new(stmt.Stmt) lbs_s_rri_stmt.InitLbsSRriStmt(op_code, suffix, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(lbs_s_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLdDriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() off := stack_items[5].Expr() ld_dri_stmt := new(stmt.Stmt) ld_dri_stmt.InitLdDriStmt(op_code, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(ld_dri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMovdDdStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DDCI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() db := stack_items[3].Token() movd_dd_stmt := new(stmt.Stmt) movd_dd_stmt.InitMovdDdStmt(op_code, dc, db) stack_item := new(StackItem) stack_item.InitStmt(movd_dd_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_rici_stmt := new(stmt.Stmt) move_rici_stmt.InitMoveRiciStmt(rc, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(move_rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_ri_stmt := new(stmt.Stmt) move_ri_stmt.InitMoveRiStmt(rc, imm) stack_item := new(StackItem) stack_item.InitStmt(move_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveSRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() condition := stack_items[6].Expr() pc := stack_items[8].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_s_rici_stmt := new(stmt.Stmt) move_s_rici_stmt.InitMoveSRiciStmt(suffix, dc, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(move_s_rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveSRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_s_ri_stmt := new(stmt.Stmt) move_s_ri_stmt.InitMoveSRiStmt(suffix, dc, imm) stack_item := new(StackItem) stack_item.InitStmt(move_s_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbIdRiiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() imm := stack_items[5].Expr() sb_id_rii_stmt := new(stmt.Stmt) sb_id_rii_stmt.InitSbIdRiiStmt(op_code, ra, off, imm) stack_item := new(StackItem) stack_item.InitStmt(sb_id_rii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbIdRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() sb_id_ri_stmt := new(stmt.Stmt) sb_id_ri_stmt.InitSbIdRiStmt(op_code, ra, off) stack_item := new(StackItem) stack_item.InitStmt(sb_id_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbRirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() rb := stack_items[5].Expr() sb_rir_stmt := new(stmt.Stmt) sb_rir_stmt.InitSbRirStmt(op_code, ra, off, rb) stack_item := new(StackItem) stack_item.InitStmt(sb_rir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSdRidStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() db := stack_items[5].Token() sd_rid_stmt := new(stmt.Stmt) sd_rid_stmt.InitSdRidStmt(op_code, ra, off, db) stack_item := new(StackItem) stack_item.InitStmt(sd_rid_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterStopStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.CI_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() token_type := op_code.CiOpCodeExpr().Token().TokenType() if token_type != lexer.STOP { err := errors.New("op code is not STOP") panic(err) } stop_stmt := new(stmt.Stmt) stop_stmt.InitStopStmt() stack_item := new(StackItem) stack_item.InitStmt(stop_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTimeCfgRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.TIME_CFG { err := errors.New("op code is not TIME_CFG") panic(err) } time_cfg_r_stmt := new(stmt.Stmt) time_cfg_r_stmt.InitTimeCfgRStmt(ra) stack_item := new(StackItem) stack_item.InitStmt(time_cfg_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLabelStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.COLON { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[0].Expr() label_stmt := new(stmt.Stmt) label_stmt.InitLabelStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(label_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } ================================================ FILE: golang/uPIMulator/src/linker/parser/rule.go ================================================ package parser import ( "errors" "uPIMulator/src/linker/lexer" ) type Reducible func([]*StackItem) bool type Reduce func([]*StackItem) *StackItem type Rule struct { precedence map[lexer.TokenType]bool reducible Reducible reduce Reduce } func (this *Rule) Init(precedence map[lexer.TokenType]bool, reducible Reducible, reduce Reduce) { this.precedence = precedence this.reducible = reducible this.reduce = reduce } func (this *Rule) IsReducible(stack_items []*StackItem, token *lexer.Token) bool { if _, found := this.precedence[token.TokenType()]; found { return false } else { return this.reducible(stack_items) } } func (this *Rule) Reduce(stack_items []*StackItem, token *lexer.Token) *StackItem { if !this.IsReducible(stack_items, token) { err := errors.New("stack items are not reducible") panic(err) } return this.reduce(stack_items) } ================================================ FILE: golang/uPIMulator/src/linker/parser/stack.go ================================================ package parser import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/stmt" ) type Stack struct { stack_items []*StackItem } func (this *Stack) Init() { this.stack_items = make([]*StackItem, 0) } func (this *Stack) Push(stack_item *StackItem) { this.stack_items = append(this.stack_items, stack_item) } func (this *Stack) Pop(num int) { this.stack_items = this.stack_items[:len(this.stack_items)-num] } func (this *Stack) Front(num int) []*StackItem { stack_items := make([]*StackItem, 0) for i := 0; i < num; i++ { stack_item := this.stack_items[len(this.stack_items)-num+i] stack_items = append(stack_items, stack_item) } return stack_items } func (this *Stack) NonStmtSize() int { non_stmt_size := 0 for i := len(this.stack_items) - 1; i >= 0; i-- { stack_item := this.stack_items[i] if stack_item.StackItemType() != STMT { non_stmt_size++ } else { break } } return non_stmt_size } func (this *Stack) AreStmts() bool { for _, stack_item := range this.stack_items { if stack_item.StackItemType() == STMT { continue } else { return false } } return true } func (this *Stack) CanAccept() bool { for i, stack_item := range this.stack_items { if i < len(this.stack_items)-1 { if stack_item.StackItemType() == STMT { continue } else { return false } } else { if stack_item.StackItemType() == TOKEN && stack_item.Token().TokenType() == lexer.END_OF_FILE { return true } else { return false } } } return false } func (this *Stack) Accept() *Ast { if !this.CanAccept() { err := errors.New("stack cannot be accepted") panic(err) } stmts := make([]*stmt.Stmt, 0) for i := 0; i < len(this.stack_items)-1; i++ { stmts = append(stmts, this.stack_items[i].Stmt()) } ast := new(Ast) ast.Init(stmts) return ast } ================================================ FILE: golang/uPIMulator/src/linker/parser/stack_item.go ================================================ package parser import ( "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" ) type StackItemType int const ( TOKEN StackItemType = iota EXPR STMT ) type StackItem struct { stack_item_type StackItemType token *lexer.Token expr *expr.Expr stmt *stmt.Stmt } func (this *StackItem) InitToken(token *lexer.Token) { this.stack_item_type = TOKEN this.token = token } func (this *StackItem) InitExpr(expr *expr.Expr) { this.stack_item_type = EXPR this.expr = expr } func (this *StackItem) InitStmt(stmt *stmt.Stmt) { this.stack_item_type = STMT this.stmt = stmt } func (this *StackItem) StackItemType() StackItemType { return this.stack_item_type } func (this *StackItem) Token() *lexer.Token { return this.token } func (this *StackItem) Expr() *expr.Expr { return this.expr } func (this *StackItem) Stmt() *stmt.Stmt { return this.stmt } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/addrsig_stmt.go ================================================ package directive type AddrsigStmt struct { } func (this *AddrsigStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/addrsig_sym_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type AddrsigSymStmt struct { expr *expr.Expr } func (this *AddrsigSymStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *AddrsigSymStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/ascii_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" ) type AsciiStmt struct { token *lexer.Token } func (this *AsciiStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *AsciiStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/asciz_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" ) type AscizStmt struct { token *lexer.Token } func (this *AscizStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *AscizStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/byte_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ByteStmt struct { expr *expr.Expr } func (this *ByteStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ByteStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/cfi_def_cfa_offset_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CfiDefCfaOffsetStmt struct { expr *expr.Expr } func (this *CfiDefCfaOffsetStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *CfiDefCfaOffsetStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/cfi_endproc.go ================================================ package directive type CfiEndprocStmt struct { } func (this *CfiEndprocStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/cfi_offset_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CfiOffsetStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *CfiOffsetStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *CfiOffsetStmt) Expr1() *expr.Expr { return this.expr1 } func (this *CfiOffsetStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/cfi_sections_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CfiSectionsStmt struct { expr *expr.Expr } func (this *CfiSectionsStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.SECTION_NAME { err := errors.New("expr is not a section name") panic(err) } this.expr = expr_ } func (this *CfiSectionsStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/cfi_startproc_stmt.go ================================================ package directive type CfiStartprocStmt struct { } func (this *CfiStartprocStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/file_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type FileNumberStmt struct { expr *expr.Expr token1 *lexer.Token token2 *lexer.Token } func (this *FileNumberStmt) Init(expr_ *expr.Expr, token1 *lexer.Token, token2 *lexer.Token) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if token1.TokenType() != lexer.STRING { err := errors.New("token1 is not a string") panic(err) } if token2.TokenType() != lexer.STRING { err := errors.New("token2 is not a string") panic(err) } this.expr = expr_ this.token1 = token1 this.token2 = token2 } func (this *FileNumberStmt) Expr() *expr.Expr { return this.expr } func (this *FileNumberStmt) Token1() *lexer.Token { return this.token1 } func (this *FileNumberStmt) Token2() *lexer.Token { return this.token2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/file_string_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" ) type FileStringStmt struct { token *lexer.Token } func (this *FileStringStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *FileStringStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/global_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type GlobalStmt struct { expr *expr.Expr } func (this *GlobalStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *GlobalStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/loc_is_stmt_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LocIsStmtStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr expr4 *expr.Expr } func (this *LocIsStmtStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, expr4 *expr.Expr, ) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } if expr4.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr4 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 this.expr4 = expr4 } func (this *LocIsStmtStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocIsStmtStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocIsStmtStmt) Expr3() *expr.Expr { return this.expr3 } func (this *LocIsStmtStmt) Expr4() *expr.Expr { return this.expr4 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/loc_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LocNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *LocNumberStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *LocNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocNumberStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/loc_prologue_end_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LocPrologueEndStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *LocPrologueEndStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *LocPrologueEndStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocPrologueEndStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocPrologueEndStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/long_program_counter.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LongProgramCounterStmt struct { expr *expr.Expr } func (this *LongProgramCounterStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *LongProgramCounterStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/long_section_name_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LongSectionNameStmt struct { expr *expr.Expr } func (this *LongSectionNameStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.SECTION_NAME { err := errors.New("expr is not a section name") panic(err) } this.expr = expr_ } func (this *LongSectionNameStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/p2_align_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type P2AlignStmt struct { expr *expr.Expr } func (this *P2AlignStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *P2AlignStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/quad_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type QuadStmt struct { expr *expr.Expr } func (this *QuadStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *QuadStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/section_identifier_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SectionIdentifierNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr token *lexer.Token expr3 *expr.Expr expr4 *expr.Expr } func (this *SectionIdentifierNumberStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, expr4 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr3.ExprType() != expr.SECTION_TYPE { err := errors.New("expr3 is not a section type") panic(err) } if expr4.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr4 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.token = token this.expr3 = expr3 this.expr4 = expr4 } func (this *SectionIdentifierNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionIdentifierNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionIdentifierNumberStmt) Token() *lexer.Token { return this.token } func (this *SectionIdentifierNumberStmt) Expr3() *expr.Expr { return this.expr3 } func (this *SectionIdentifierNumberStmt) Expr4() *expr.Expr { return this.expr4 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/section_identifier_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SectionIdentifierStmt struct { expr1 *expr.Expr expr2 *expr.Expr token *lexer.Token expr3 *expr.Expr } func (this *SectionIdentifierStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr3.ExprType() != expr.SECTION_TYPE { err := errors.New("expr3 is not a section type") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.token = token this.expr3 = expr3 } func (this *SectionIdentifierStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionIdentifierStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionIdentifierStmt) Token() *lexer.Token { return this.token } func (this *SectionIdentifierStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/section_stack_sizes_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SectionStackSizesStmt struct { token *lexer.Token expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *SectionStackSizesStmt) Init( token *lexer.Token, expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, ) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr1.ExprType() != expr.SECTION_TYPE { err := errors.New("expr1 is not a section type") panic(err) } if expr2.ExprType() != expr.SECTION_NAME { err := errors.New("expr2 is not a section name") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.token = token this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *SectionStackSizesStmt) Token() *lexer.Token { return this.token } func (this *SectionStackSizesStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStackSizesStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionStackSizesStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/section_string_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SectionStringNumberStmt struct { expr1 *expr.Expr token *lexer.Token expr2 *expr.Expr expr3 *expr.Expr } func (this *SectionStringNumberStmt) Init( expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr, expr3 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr2.ExprType() != expr.SECTION_TYPE { err := errors.New("expr2 is not a section type") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.token = token this.expr2 = expr2 this.expr3 = expr3 } func (this *SectionStringNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStringNumberStmt) Token() *lexer.Token { return this.token } func (this *SectionStringNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionStringNumberStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/section_string_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SectionStringStmt struct { expr1 *expr.Expr token *lexer.Token expr2 *expr.Expr } func (this *SectionStringStmt) Init(expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr2.ExprType() != expr.SECTION_TYPE { err := errors.New("expr2 is not a section type") panic(err) } this.expr1 = expr1 this.token = token this.expr2 = expr2 } func (this *SectionStringStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStringStmt) Token() *lexer.Token { return this.token } func (this *SectionStringStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/set_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type SetStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *SetStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *SetStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SetStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/short_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ShortStmt struct { expr *expr.Expr } func (this *ShortStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ShortStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/size_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type SizeStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *SizeStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *SizeStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SizeStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/text_stmt.go ================================================ package directive type TextStmt struct { } func (this *TextStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/type_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type TypeStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *TypeStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.SYMBOL_TYPE { err := errors.New("expr is not a symbol type") panic(err) } this.expr1 = expr2 } func (this *TypeStmt) Expr1() *expr.Expr { return this.expr1 } func (this *TypeStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/weak_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type WeakStmt struct { expr *expr.Expr } func (this *WeakStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *WeakStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/zero_double_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ZeroDoubleNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *ZeroDoubleNumberStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *ZeroDoubleNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *ZeroDoubleNumberStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/directive/zero_single_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ZeroSingleNumberStmt struct { expr *expr.Expr } func (this *ZeroSingleNumberStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ZeroSingleNumberStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/ci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CiStmt struct { op_code *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *CiStmt) Init(op_code *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.CI_OP_CODE { err := errors.New("op code is not a CI op code") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.condition = condition this.pc = pc } func (this *CiStmt) OpCode() *expr.Expr { return this.op_code } func (this *CiStmt) Condition() *expr.Expr { return this.condition } func (this *CiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/ddci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type DdciStmt struct { op_code *expr.Expr dc *lexer.Token db *lexer.Token condition *expr.Expr pc *expr.Expr } func (this *DdciStmt) Init( op_code *expr.Expr, dc *lexer.Token, db *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.DDCI_OP_CODE { err := errors.New("op code is not a DDCI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.db = db this.condition = condition this.pc = pc } func (this *DdciStmt) OpCode() *expr.Expr { return this.op_code } func (this *DdciStmt) Dc() *lexer.Token { return this.dc } func (this *DdciStmt) Db() *lexer.Token { return this.db } func (this *DdciStmt) Condition() *expr.Expr { return this.condition } func (this *DdciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/dma_rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type DmaRriStmt struct { op_code *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *DmaRriStmt) Init(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.DMA_RRI_OP_CODE { err := errors.New("op code is not a DMA_RRI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.rb = rb this.imm = imm } func (this *DmaRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *DmaRriStmt) Ra() *expr.Expr { return this.ra } func (this *DmaRriStmt) Rb() *expr.Expr { return this.rb } func (this *DmaRriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/drdici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type DrdiciStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr db *lexer.Token imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *DrdiciStmt) Init( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.DRDICI_OP_CODE { err := errors.New("op code is not a DRDICI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.db = db this.imm = imm this.condition = condition this.pc = pc } func (this *DrdiciStmt) OpCode() *expr.Expr { return this.op_code } func (this *DrdiciStmt) Dc() *lexer.Token { return this.dc } func (this *DrdiciStmt) Ra() *expr.Expr { return this.ra } func (this *DrdiciStmt) Db() *lexer.Token { return this.db } func (this *DrdiciStmt) Imm() *expr.Expr { return this.imm } func (this *DrdiciStmt) Condition() *expr.Expr { return this.condition } func (this *DrdiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/edri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type EdriStmt struct { op_code *expr.Expr endian *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *EdriStmt) Init( op_code *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.dc = dc this.ra = ra this.off = off } func (this *EdriStmt) OpCode() *expr.Expr { return this.op_code } func (this *EdriStmt) Endian() *expr.Expr { return this.endian } func (this *EdriStmt) Dc() *lexer.Token { return this.dc } func (this *EdriStmt) Ra() *expr.Expr { return this.ra } func (this *EdriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/erid_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type EridStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr db *lexer.Token } func (this *EridStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.db = db } func (this *EridStmt) OpCode() *expr.Expr { return this.op_code } func (this *EridStmt) Endian() *expr.Expr { return this.endian } func (this *EridStmt) Ra() *expr.Expr { return this.ra } func (this *EridStmt) Off() *expr.Expr { return this.off } func (this *EridStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/erii_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type EriiStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr imm *expr.Expr } func (this *EriiStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.imm = imm } func (this *EriiStmt) OpCode() *expr.Expr { return this.op_code } func (this *EriiStmt) Endian() *expr.Expr { return this.endian } func (this *EriiStmt) Ra() *expr.Expr { return this.ra } func (this *EriiStmt) Off() *expr.Expr { return this.off } func (this *EriiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/erir_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ErirStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr rb *expr.Expr } func (this *ErirStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.rb = rb } func (this *ErirStmt) OpCode() *expr.Expr { return this.op_code } func (this *ErirStmt) Endian() *expr.Expr { return this.endian } func (this *ErirStmt) Ra() *expr.Expr { return this.ra } func (this *ErirStmt) Off() *expr.Expr { return this.off } func (this *ErirStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/erri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type ErriStmt struct { op_code *expr.Expr endian *expr.Expr rc *expr.Expr ra *expr.Expr off *expr.Expr } func (this *ErriStmt) Init( op_code *expr.Expr, endian *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.rc = rc this.ra = ra this.off = off } func (this *ErriStmt) OpCode() *expr.Expr { return this.op_code } func (this *ErriStmt) Endian() *expr.Expr { return this.endian } func (this *ErriStmt) Rc() *expr.Expr { return this.rc } func (this *ErriStmt) Ra() *expr.Expr { return this.ra } func (this *ErriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/i_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type IStmt struct { op_code *expr.Expr imm *expr.Expr } func (this *IStmt) Init(op_code *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.I_OP_CODE { err := errors.New("op code is not an I op code") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.imm = imm } func (this *IStmt) OpCode() *expr.Expr { return this.op_code } func (this *IStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/nop_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type NopStmt struct { op_code *expr.Expr } func (this *NopStmt) Init(op_code *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } this.op_code = op_code } func (this *NopStmt) OpCode() *expr.Expr { return this.op_code } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/r_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RStmt struct { op_code *expr.Expr rc *expr.Expr } func (this *RStmt) Init(op_code *expr.Expr, rc *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } this.op_code = op_code this.rc = rc } func (this *RStmt) OpCode() *expr.Expr { return this.op_code } func (this *RStmt) Rc() *expr.Expr { return this.rc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RciStmt struct { op_code *expr.Expr rc *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RciStmt) Init(op_code *expr.Expr, rc *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.condition = condition this.pc = pc } func (this *RciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RciStmt) Rc() *expr.Expr { return this.rc } func (this *RciStmt) Condition() *expr.Expr { return this.condition } func (this *RciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RiciStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RiciStmt) Init( op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RICI_OP_CODE { err := errors.New("op code is not an RICI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *RiciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RiciStmt) Ra() *expr.Expr { return this.ra } func (this *RiciStmt) Imm() *expr.Expr { return this.imm } func (this *RiciStmt) Condition() *expr.Expr { return this.condition } func (this *RiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rir_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RirStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr } func (this *RirStmt) Init(op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra } func (this *RirStmt) OpCode() *expr.Expr { return this.op_code } func (this *RirStmt) Rc() *expr.Expr { return this.rc } func (this *RirStmt) Imm() *expr.Expr { return this.imm } func (this *RirStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rirc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RircStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *RircStmt) Init( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra this.condition = condition } func (this *RircStmt) OpCode() *expr.Expr { return this.op_code } func (this *RircStmt) Rc() *expr.Expr { return this.rc } func (this *RircStmt) Imm() *expr.Expr { return this.imm } func (this *RircStmt) Ra() *expr.Expr { return this.ra } func (this *RircStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rirci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RirciStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RirciStmt) Init( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra this.condition = condition this.pc = pc } func (this *RirciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RirciStmt) Rc() *expr.Expr { return this.rc } func (this *RirciStmt) Imm() *expr.Expr { return this.imm } func (this *RirciStmt) Ra() *expr.Expr { return this.ra } func (this *RirciStmt) Condition() *expr.Expr { return this.condition } func (this *RirciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr } func (this *RrStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra } func (this *RrStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrStmt) Rc() *expr.Expr { return this.rc } func (this *RrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrcStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *RrcStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.condition = condition } func (this *RrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrcStmt) Rc() *expr.Expr { return this.rc } func (this *RrcStmt) Ra() *expr.Expr { return this.ra } func (this *RrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.condition = condition this.pc = pc } func (this *RrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrciStmt) Rc() *expr.Expr { return this.rc } func (this *RrciStmt) Ra() *expr.Expr { return this.ra } func (this *RrciStmt) Condition() *expr.Expr { return this.condition } func (this *RrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr } func (this *RriStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm } func (this *RriStmt) OpCode() *expr.Expr { return this.op_code } func (this *RriStmt) Rc() *expr.Expr { return this.rc } func (this *RriStmt) Ra() *expr.Expr { return this.ra } func (this *RriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rric_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RricStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr } func (this *RricStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm this.condition = condition } func (this *RricStmt) OpCode() *expr.Expr { return this.op_code } func (this *RricStmt) Rc() *expr.Expr { return this.rc } func (this *RricStmt) Ra() *expr.Expr { return this.ra } func (this *RricStmt) Imm() *expr.Expr { return this.imm } func (this *RricStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RriciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RriciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *RriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RriciStmt) Rc() *expr.Expr { return this.rc } func (this *RriciStmt) Ra() *expr.Expr { return this.ra } func (this *RriciStmt) Imm() *expr.Expr { return this.imm } func (this *RriciStmt) Condition() *expr.Expr { return this.condition } func (this *RriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrrStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr } func (this *RrrStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb } func (this *RrrStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrStmt) Rc() *expr.Expr { return this.rc } func (this *RrrStmt) Ra() *expr.Expr { return this.ra } func (this *RrrStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrrcStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr condition *expr.Expr } func (this *RrrcStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.condition = condition } func (this *RrrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrcStmt) Rc() *expr.Expr { return this.rc } func (this *RrrcStmt) Ra() *expr.Expr { return this.ra } func (this *RrrcStmt) Rb() *expr.Expr { return this.rb } func (this *RrrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrrciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrrciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.condition = condition this.pc = pc } func (this *RrrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrciStmt) Rc() *expr.Expr { return this.rc } func (this *RrrciStmt) Ra() *expr.Expr { return this.ra } func (this *RrrciStmt) Rb() *expr.Expr { return this.rb } func (this *RrrciStmt) Condition() *expr.Expr { return this.condition } func (this *RrrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *RrriStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.imm = imm } func (this *RrriStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrriStmt) Rc() *expr.Expr { return this.rc } func (this *RrriStmt) Ra() *expr.Expr { return this.ra } func (this *RrriStmt) Rb() *expr.Expr { return this.rb } func (this *RrriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/rrrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/parser/expr" ) type RrriciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrriciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.imm = imm this.condition = condition this.pc = pc } func (this *RrriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrriciStmt) Rc() *expr.Expr { return this.rc } func (this *RrriciStmt) Ra() *expr.Expr { return this.ra } func (this *RrriciStmt) Rb() *expr.Expr { return this.rb } func (this *RrriciStmt) Imm() *expr.Expr { return this.imm } func (this *RrriciStmt) Condition() *expr.Expr { return this.condition } func (this *RrriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_erri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SErriStmt struct { op_code *expr.Expr suffix *expr.Expr endian *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *SErriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.endian = endian this.dc = dc this.ra = ra this.off = off } func (this *SErriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SErriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SErriStmt) Endian() *expr.Expr { return this.endian } func (this *SErriStmt) Dc() *lexer.Token { return this.dc } func (this *SErriStmt) Ra() *expr.Expr { return this.ra } func (this *SErriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_r_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token } func (this *SRStmt) Init(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc } func (this *SRStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRStmt) Dc() *lexer.Token { return this.dc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token condition *expr.Expr pc *expr.Expr } func (this *SRciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.condition = condition this.pc = pc } func (this *SRciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRciStmt) Dc() *lexer.Token { return this.dc } func (this *SRciStmt) Condition() *expr.Expr { return this.condition } func (this *SRciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rirc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRircStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token imm *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *SRircStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = imm this.ra = ra this.condition = condition } func (this *SRircStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRircStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRircStmt) Dc() *lexer.Token { return this.dc } func (this *SRircStmt) Imm() *expr.Expr { return this.imm } func (this *SRircStmt) Ra() *expr.Expr { return this.ra } func (this *SRircStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rirci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRirciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token imm *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRirciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = imm this.ra = ra this.condition = condition this.pc = pc } func (this *SRirciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRirciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRirciStmt) Dc() *lexer.Token { return this.dc } func (this *SRirciStmt) Imm() *expr.Expr { return this.imm } func (this *SRirciStmt) Ra() *expr.Expr { return this.ra } func (this *SRirciStmt) Condition() *expr.Expr { return this.condition } func (this *SRirciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr } func (this *SRrStmt) Init(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra } func (this *SRrStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrStmt) Dc() *lexer.Token { return this.dc } func (this *SRrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrcStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr condition *expr.Expr } func (this *SRrcStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.condition = condition } func (this *SRrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrcStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrcStmt) Dc() *lexer.Token { return this.dc } func (this *SRrcStmt) Ra() *expr.Expr { return this.ra } func (this *SRrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.condition = condition this.pc = pc } func (this *SRrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr } func (this *SRriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm } func (this *SRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRriStmt) Dc() *lexer.Token { return this.dc } func (this *SRriStmt) Ra() *expr.Expr { return this.ra } func (this *SRriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rric_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRricStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr condition *expr.Expr } func (this *SRricStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm this.condition = condition } func (this *SRricStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRricStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRricStmt) Dc() *lexer.Token { return this.dc } func (this *SRricStmt) Ra() *expr.Expr { return this.ra } func (this *SRricStmt) Imm() *expr.Expr { return this.imm } func (this *SRricStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRriciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRriciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *SRriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRriciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRriciStmt) Dc() *lexer.Token { return this.dc } func (this *SRriciStmt) Ra() *expr.Expr { return this.ra } func (this *SRriciStmt) Imm() *expr.Expr { return this.imm } func (this *SRriciStmt) Condition() *expr.Expr { return this.condition } func (this *SRriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrrStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr } func (this *SRrrStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb } func (this *SRrrStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrrcStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr condition *expr.Expr } func (this *SRrrcStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.condition = condition } func (this *SRrrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrcStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrcStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrcStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrcStmt) Rb() *expr.Expr { return this.rb } func (this *SRrrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrrciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrrciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.condition = condition this.pc = pc } func (this *SRrrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrciStmt) Rb() *expr.Expr { return this.rb } func (this *SRrrciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *SRrriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = imm } func (this *SRrriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrriStmt) Dc() *lexer.Token { return this.dc } func (this *SRrriStmt) Ra() *expr.Expr { return this.ra } func (this *SRrriStmt) Rb() *expr.Expr { return this.rb } func (this *SRrriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/instruction/s_rrrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SRrriciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrriciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = imm this.condition = condition this.pc = pc } func (this *SRrriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrriciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrriciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrriciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrriciStmt) Rb() *expr.Expr { return this.rb } func (this *SRrriciStmt) Imm() *expr.Expr { return this.imm } func (this *SRrriciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/label_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LabelStmt struct { expr *expr.Expr } func (this *LabelStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.expr = expr_ } func (this *LabelStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/stmt.go ================================================ package stmt import ( "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt/directive" "uPIMulator/src/linker/parser/stmt/instruction" "uPIMulator/src/linker/parser/stmt/sugar" ) type StmtType int const ( ADDRSIG StmtType = iota ADDRSIG_SYM ASCII ASCIZ BYTE CFI_DEF_CFA_OFFSET CFI_ENDPROC CFI_OFFSET CFI_SECTIONS CFI_STARTPROC FILE_NUMBER FILE_STRING GLOBAL LOC_IS_STMT LOC_NUMBER LOC_PROLOGUE_END LONG_PROGRAM_COUNTER LONG_SECTION_NAME P2_ALIGN QUAD SECTION_IDENTIFIER_NUMBER SECTION_IDENTIFIER SECTION_STACK_SIZES SECTION_STRING_NUMBER SECTION_STRING SET SHORT SIZE TEXT TYPE WEAK ZERO_SINGLE_NUMBER ZERO_DOUBLE_NUMBER RICI RRI RRIC RRICI RRR RRRC RRRCI S_RRI S_RRIC S_RRICI S_RRR S_RRRC S_RRRCI RR RRC RRCI S_RR S_RRC S_RRCI DRDICI RRRI RRRICI S_RRRI S_RRRICI RIR RIRC RIRCI S_RIRC S_RIRCI R RCI S_R S_RCI CI I DDCI ERRI EDRI S_ERRI ERII ERIR ERID DMA_RRI NOP MOVE_RI MOVE_RICI MOVE_S_RI MOVE_S_RICI JEQ_RII JEQ_RRI JNZ_RI JUMP_I JUMP_R DIV_STEP_DRDI BOOT_RI STOP CALL_RI CALL_RR BKP MOVD_DD TIME_CFG_R LBS_RRI LBS_S_RRI LD_DRI SB_RIR SB_ID_RII SB_ID_RI SD_RID LABEL ) type Stmt struct { stmt_type StmtType addrsig_stmt *directive.AddrsigStmt addrsig_sym_stmt *directive.AddrsigSymStmt ascii_stmt *directive.AsciiStmt asciz_stmt *directive.AscizStmt byte_stmt *directive.ByteStmt cfi_def_cfa_offset_stmt *directive.CfiDefCfaOffsetStmt cfi_endproc_stmt *directive.CfiEndprocStmt cfi_offset_stmt *directive.CfiOffsetStmt cfi_sections_stmt *directive.CfiSectionsStmt cfi_startproc_stmt *directive.CfiStartprocStmt file_number_stmt *directive.FileNumberStmt file_string_stmt *directive.FileStringStmt global_stmt *directive.GlobalStmt loc_is_stmt_stmt *directive.LocIsStmtStmt loc_number_stmt *directive.LocNumberStmt loc_prologue_end_stmt *directive.LocPrologueEndStmt long_program_counter_stmt *directive.LongProgramCounterStmt long_section_name_stmt *directive.LongSectionNameStmt p2_align_stmt *directive.P2AlignStmt quad_stmt *directive.QuadStmt section_identifier_number_stmt *directive.SectionIdentifierNumberStmt section_identifier_stmt *directive.SectionIdentifierStmt section_stack_sizes_stmt *directive.SectionStackSizesStmt section_string_number_stmt *directive.SectionStringNumberStmt section_string_stmt *directive.SectionStringStmt set_stmt *directive.SetStmt short_stmt *directive.ShortStmt size_stmt *directive.SizeStmt text_stmt *directive.TextStmt type_stmt *directive.TypeStmt weak_stmt *directive.WeakStmt zero_single_number_stmt *directive.ZeroSingleNumberStmt zero_double_number_stmt *directive.ZeroDoubleNumberStmt ci_stmt *instruction.CiStmt ddci_stmt *instruction.DdciStmt dma_rri_stmt *instruction.DmaRriStmt drdici_stmt *instruction.DrdiciStmt edri_stmt *instruction.EdriStmt erid_stmt *instruction.EridStmt erii_stmt *instruction.EriiStmt erir_stmt *instruction.ErirStmt erri_stmt *instruction.ErriStmt i_stmt *instruction.IStmt nop_stmt *instruction.NopStmt r_stmt *instruction.RStmt rci_stmt *instruction.RciStmt rici_stmt *instruction.RiciStmt rir_stmt *instruction.RirStmt rirc_stmt *instruction.RircStmt rirci_stmt *instruction.RirciStmt rr_stmt *instruction.RrStmt rrc_stmt *instruction.RrcStmt rrci_stmt *instruction.RrciStmt rri_stmt *instruction.RriStmt rric_stmt *instruction.RricStmt rrici_stmt *instruction.RriciStmt rrr_stmt *instruction.RrrStmt rrrc_stmt *instruction.RrrcStmt rrrci_stmt *instruction.RrrciStmt rrri_stmt *instruction.RrriStmt rrrici_stmt *instruction.RrriciStmt s_erri_stmt *instruction.SErriStmt s_r_stmt *instruction.SRStmt s_rci_stmt *instruction.SRciStmt s_rirc_stmt *instruction.SRircStmt s_rirci_stmt *instruction.SRirciStmt s_rr_stmt *instruction.SRrStmt s_rrc_stmt *instruction.SRrcStmt s_rrci_stmt *instruction.SRrciStmt s_rri_stmt *instruction.SRriStmt s_rric_stmt *instruction.SRricStmt s_rrici_stmt *instruction.SRriciStmt s_rrr_stmt *instruction.SRrrStmt s_rrrc_stmt *instruction.SRrrcStmt s_rrrci_stmt *instruction.SRrrciStmt s_rrri_stmt *instruction.SRrriStmt s_rrrici_stmt *instruction.SRrriciStmt bkp_stmt *sugar.BkpStmt boot_ri_stmt *sugar.BootRiStmt call_ri_stmt *sugar.CallRiStmt call_rr_stmt *sugar.CallRrStmt div_step_drdi_stmt *sugar.DivStepDrdiStmt jeq_rii_stmt *sugar.JeqRiiStmt jeq_rri_stmt *sugar.JeqRriStmt jnz_ri_stmt *sugar.JnzRiStmt jump_i_stmt *sugar.JumpIStmt jump_r_stmt *sugar.JumpRStmt lbs_rri_stmt *sugar.LbsRriStmt lbs_s_rri_stmt *sugar.LbsSRriStmt ld_dri_stmt *sugar.LdDriStmt movd_dd_stmt *sugar.MovdDdStmt move_ri_stmt *sugar.MoveRiStmt move_rici_stmt *sugar.MoveRiciStmt move_s_ri_stmt *sugar.MoveSRiStmt move_s_rici_stmt *sugar.MoveSRiciStmt sb_id_ri_stmt *sugar.SbIdRiStmt sb_id_rii_stmt *sugar.SbIdRiiStmt sb_rir_stmt *sugar.SbRirStmt sd_rid_stmt *sugar.SdRidStmt stop_stmt *sugar.StopStmt time_cfg_r_stmt *sugar.TimeCfgRStmt label_stmt *LabelStmt } func (this *Stmt) InitAddrsigStmt() { this.stmt_type = ADDRSIG this.addrsig_stmt = new(directive.AddrsigStmt) this.addrsig_stmt.Init() } func (this *Stmt) InitAddrsigSymStmt(expr_ *expr.Expr) { this.stmt_type = ADDRSIG_SYM this.addrsig_sym_stmt = new(directive.AddrsigSymStmt) this.addrsig_sym_stmt.Init(expr_) } func (this *Stmt) InitAsciiStmt(token *lexer.Token) { this.stmt_type = ASCII this.ascii_stmt = new(directive.AsciiStmt) this.ascii_stmt.Init(token) } func (this *Stmt) InitAscizStmt(token *lexer.Token) { this.stmt_type = ASCIZ this.asciz_stmt = new(directive.AscizStmt) this.asciz_stmt.Init(token) } func (this *Stmt) InitByteStmt(expr_ *expr.Expr) { this.stmt_type = BYTE this.byte_stmt = new(directive.ByteStmt) this.byte_stmt.Init(expr_) } func (this *Stmt) InitCfiDefCfaOffsetStmt(expr_ *expr.Expr) { this.stmt_type = CFI_DEF_CFA_OFFSET this.cfi_def_cfa_offset_stmt = new(directive.CfiDefCfaOffsetStmt) this.cfi_def_cfa_offset_stmt.Init(expr_) } func (this *Stmt) InitCfiEndprocStmt() { this.stmt_type = CFI_ENDPROC this.cfi_endproc_stmt = new(directive.CfiEndprocStmt) this.cfi_endproc_stmt.Init() } func (this *Stmt) InitCfiOffsetStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = CFI_OFFSET this.cfi_offset_stmt = new(directive.CfiOffsetStmt) this.cfi_offset_stmt.Init(expr1, expr2) } func (this *Stmt) InitCfiSectionsStmt(expr_ *expr.Expr) { this.stmt_type = CFI_SECTIONS this.cfi_sections_stmt = new(directive.CfiSectionsStmt) this.cfi_sections_stmt.Init(expr_) } func (this *Stmt) InitCfiStartprocStmt() { this.stmt_type = CFI_STARTPROC this.cfi_startproc_stmt = new(directive.CfiStartprocStmt) this.cfi_startproc_stmt.Init() } func (this *Stmt) InitFileNumberStmt(expr_ *expr.Expr, token1 *lexer.Token, token2 *lexer.Token) { this.stmt_type = FILE_NUMBER this.file_number_stmt = new(directive.FileNumberStmt) this.file_number_stmt.Init(expr_, token1, token2) } func (this *Stmt) InitFileStringStmt(token *lexer.Token) { this.stmt_type = FILE_STRING this.file_string_stmt = new(directive.FileStringStmt) this.file_string_stmt.Init(token) } func (this *Stmt) InitGlobalStmt(expr_ *expr.Expr) { this.stmt_type = GLOBAL this.global_stmt = new(directive.GlobalStmt) this.global_stmt.Init(expr_) } func (this *Stmt) InitLocIsStmtStmt( expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, expr4 *expr.Expr, ) { this.stmt_type = LOC_IS_STMT this.loc_is_stmt_stmt = new(directive.LocIsStmtStmt) this.loc_is_stmt_stmt.Init(expr1, expr2, expr3, expr4) } func (this *Stmt) InitLocNumberStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = LOC_NUMBER this.loc_number_stmt = new(directive.LocNumberStmt) this.loc_number_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitLocPrologueEndStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = LOC_PROLOGUE_END this.loc_prologue_end_stmt = new(directive.LocPrologueEndStmt) this.loc_prologue_end_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitLongProgramCounterStmt(expr_ *expr.Expr) { this.stmt_type = LONG_PROGRAM_COUNTER this.long_program_counter_stmt = new(directive.LongProgramCounterStmt) this.long_program_counter_stmt.Init(expr_) } func (this *Stmt) InitLongSectionNameStmt(expr_ *expr.Expr) { this.stmt_type = LONG_SECTION_NAME this.long_section_name_stmt = new(directive.LongSectionNameStmt) this.long_section_name_stmt.Init(expr_) } func (this *Stmt) InitP2AlignStmt(expr_ *expr.Expr) { this.stmt_type = P2_ALIGN this.p2_align_stmt = new(directive.P2AlignStmt) this.p2_align_stmt.Init(expr_) } func (this *Stmt) InitQuadStmt(expr_ *expr.Expr) { this.stmt_type = QUAD this.quad_stmt = new(directive.QuadStmt) this.quad_stmt.Init(expr_) } func (this *Stmt) InitSectionIdentifierNumberStmt( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, expr4 *expr.Expr, ) { this.stmt_type = SECTION_IDENTIFIER_NUMBER this.section_identifier_number_stmt = new(directive.SectionIdentifierNumberStmt) this.section_identifier_number_stmt.Init(expr1, expr2, token, expr3, expr4) } func (this *Stmt) InitSectionIdentifierStmt( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, ) { this.stmt_type = SECTION_IDENTIFIER this.section_identifier_stmt = new(directive.SectionIdentifierStmt) this.section_identifier_stmt.Init(expr1, expr2, token, expr3) } func (this *Stmt) InitSectionStackSizesStmt( token *lexer.Token, expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, ) { this.stmt_type = SECTION_STACK_SIZES this.section_stack_sizes_stmt = new(directive.SectionStackSizesStmt) this.section_stack_sizes_stmt.Init(token, expr1, expr2, expr3) } func (this *Stmt) InitSectionStringNumberStmt( expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr, expr3 *expr.Expr, ) { this.stmt_type = SECTION_STRING_NUMBER this.section_string_number_stmt = new(directive.SectionStringNumberStmt) this.section_string_number_stmt.Init(expr1, token, expr2, expr3) } func (this *Stmt) InitSectionStringStmt(expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr) { this.stmt_type = SECTION_STRING this.section_string_stmt = new(directive.SectionStringStmt) this.section_string_stmt.Init(expr1, token, expr2) } func (this *Stmt) InitSetStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = SET this.set_stmt = new(directive.SetStmt) this.set_stmt.Init(expr1, expr2) } func (this *Stmt) InitShortStmt(expr_ *expr.Expr) { this.stmt_type = SHORT this.short_stmt = new(directive.ShortStmt) this.short_stmt.Init(expr_) } func (this *Stmt) InitSizeStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = SIZE this.size_stmt = new(directive.SizeStmt) this.size_stmt.Init(expr1, expr2) } func (this *Stmt) InitTextStmt() { this.stmt_type = TEXT this.text_stmt = new(directive.TextStmt) this.text_stmt.Init() } func (this *Stmt) InitTypeStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = TYPE this.type_stmt = new(directive.TypeStmt) this.type_stmt.Init(expr1, expr2) } func (this *Stmt) InitWeakStmt(expr_ *expr.Expr) { this.stmt_type = WEAK this.weak_stmt = new(directive.WeakStmt) this.weak_stmt.Init(expr_) } func (this *Stmt) InitZeroSingleNumberStmt(expr_ *expr.Expr) { this.stmt_type = ZERO_SINGLE_NUMBER this.zero_single_number_stmt = new(directive.ZeroSingleNumberStmt) this.zero_single_number_stmt.Init(expr_) } func (this *Stmt) InitZeroDoubleNumberStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = ZERO_DOUBLE_NUMBER this.zero_double_number_stmt = new(directive.ZeroDoubleNumberStmt) this.zero_double_number_stmt.Init(expr1, expr2) } func (this *Stmt) InitCiStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = CI this.ci_stmt = new(instruction.CiStmt) this.ci_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitDdciStmt( op_code *expr.Expr, dc *lexer.Token, db *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = DDCI this.ddci_stmt = new(instruction.DdciStmt) this.ddci_stmt.Init(op_code, dc, db, condition, pc) } func (this *Stmt) InitDmaRriStmt(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr) { this.stmt_type = DMA_RRI this.dma_rri_stmt = new(instruction.DmaRriStmt) this.dma_rri_stmt.Init(op_code, ra, rb, imm) } func (this *Stmt) InitDrdiciStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = DRDICI this.drdici_stmt = new(instruction.DrdiciStmt) this.drdici_stmt.Init(op_code, dc, ra, db, imm, condition, pc) } func (this *Stmt) InitEdriStmt( op_code *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = EDRI this.edri_stmt = new(instruction.EdriStmt) this.edri_stmt.Init(op_code, endian, dc, ra, off) } func (this *Stmt) InitEridStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { this.stmt_type = ERID this.erid_stmt = new(instruction.EridStmt) this.erid_stmt.Init(op_code, endian, ra, off, db) } func (this *Stmt) InitEriiStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { this.stmt_type = ERII this.erii_stmt = new(instruction.EriiStmt) this.erii_stmt.Init(op_code, endian, ra, off, imm) } func (this *Stmt) InitErirStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr, ) { this.stmt_type = ERIR this.erir_stmt = new(instruction.ErirStmt) this.erir_stmt.Init(op_code, endian, ra, off, rb) } func (this *Stmt) InitErriStmt( op_code *expr.Expr, endian *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = ERRI this.erri_stmt = new(instruction.ErriStmt) this.erri_stmt.Init(op_code, endian, rc, ra, off) } func (this *Stmt) InitIStmt(op_code *expr.Expr, imm *expr.Expr) { this.stmt_type = I this.i_stmt = new(instruction.IStmt) this.i_stmt.Init(op_code, imm) } func (this *Stmt) InitNopStmt(op_code *expr.Expr) { this.stmt_type = NOP this.nop_stmt = new(instruction.NopStmt) this.nop_stmt.Init(op_code) } func (this *Stmt) InitRStmt(op_code *expr.Expr, rc *expr.Expr) { this.stmt_type = R this.r_stmt = new(instruction.RStmt) this.r_stmt.Init(op_code, rc) } func (this *Stmt) InitRciStmt( op_code *expr.Expr, rc *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RCI this.rci_stmt = new(instruction.RciStmt) this.rci_stmt.Init(op_code, rc, condition, pc) } func (this *Stmt) InitRiciStmt( op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RICI this.rici_stmt = new(instruction.RiciStmt) this.rici_stmt.Init(op_code, ra, imm, condition, pc) } func (this *Stmt) InitRirStmt(op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr) { this.stmt_type = RIR this.rir_stmt = new(instruction.RirStmt) this.rir_stmt.Init(op_code, rc, imm, ra) } func (this *Stmt) InitRircStmt( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RIRC this.rirc_stmt = new(instruction.RircStmt) this.rirc_stmt.Init(op_code, rc, imm, ra, condition) } func (this *Stmt) InitRirciStmt( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RIRCI this.rirci_stmt = new(instruction.RirciStmt) this.rirci_stmt.Init(op_code, rc, imm, ra, condition, pc) } func (this *Stmt) InitRrStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr) { this.stmt_type = RR this.rr_stmt = new(instruction.RrStmt) this.rr_stmt.Init(op_code, rc, ra) } func (this *Stmt) InitRrcStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRC this.rrc_stmt = new(instruction.RrcStmt) this.rrc_stmt.Init(op_code, rc, ra, condition) } func (this *Stmt) InitRrciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRCI this.rrci_stmt = new(instruction.RrciStmt) this.rrci_stmt.Init(op_code, rc, ra, condition, pc) } func (this *Stmt) InitRriStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr) { this.stmt_type = RRI this.rri_stmt = new(instruction.RriStmt) this.rri_stmt.Init(op_code, rc, ra, imm) } func (this *Stmt) InitRricStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRIC this.rric_stmt = new(instruction.RricStmt) this.rric_stmt.Init(op_code, rc, ra, imm, condition) } func (this *Stmt) InitRriciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRICI this.rrici_stmt = new(instruction.RriciStmt) this.rrici_stmt.Init(op_code, rc, ra, imm, condition, pc) } func (this *Stmt) InitRrrStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr) { this.stmt_type = RRR this.rrr_stmt = new(instruction.RrrStmt) this.rrr_stmt.Init(op_code, rc, ra, rb) } func (this *Stmt) InitRrrcStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRRC this.rrrc_stmt = new(instruction.RrrcStmt) this.rrrc_stmt.Init(op_code, rc, ra, rb, condition) } func (this *Stmt) InitRrrciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRRCI this.rrrci_stmt = new(instruction.RrrciStmt) this.rrrci_stmt.Init(op_code, rc, ra, rb, condition, pc) } func (this *Stmt) InitRrriStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { this.stmt_type = RRRI this.rrri_stmt = new(instruction.RrriStmt) this.rrri_stmt.Init(op_code, rc, ra, rb, imm) } func (this *Stmt) InitRrriciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRRICI this.rrrici_stmt = new(instruction.RrriciStmt) this.rrrici_stmt.Init(op_code, rc, ra, rb, imm, condition, pc) } func (this *Stmt) InitSErriStmt( op_code *expr.Expr, suffix *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = S_ERRI this.s_erri_stmt = new(instruction.SErriStmt) this.s_erri_stmt.Init(op_code, suffix, endian, dc, ra, off) } func (this *Stmt) InitSRStmt(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token) { this.stmt_type = S_R this.s_r_stmt = new(instruction.SRStmt) this.s_r_stmt.Init(op_code, suffix, dc) } func (this *Stmt) InitSRciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RCI this.s_rci_stmt = new(instruction.SRciStmt) this.s_rci_stmt.Init(op_code, suffix, dc, condition, pc) } func (this *Stmt) InitSRircStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RIRC this.s_rirc_stmt = new(instruction.SRircStmt) this.s_rirc_stmt.Init(op_code, suffix, dc, imm, ra, condition) } func (this *Stmt) InitSRirciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RIRCI this.s_rirci_stmt = new(instruction.SRirciStmt) this.s_rirci_stmt.Init(op_code, suffix, dc, imm, ra, condition, pc) } func (this *Stmt) InitSRrStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, ) { this.stmt_type = S_RR this.s_rr_stmt = new(instruction.SRrStmt) this.s_rr_stmt.Init(op_code, suffix, dc, ra) } func (this *Stmt) InitSRrcStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRC this.s_rrc_stmt = new(instruction.SRrcStmt) this.s_rrc_stmt.Init(op_code, suffix, dc, ra, condition) } func (this *Stmt) InitSRrciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRCI this.s_rrci_stmt = new(instruction.SRrciStmt) this.s_rrci_stmt.Init(op_code, suffix, dc, ra, condition, pc) } func (this *Stmt) InitSRriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, ) { this.stmt_type = S_RRI this.s_rri_stmt = new(instruction.SRriStmt) this.s_rri_stmt.Init(op_code, suffix, dc, ra, imm) } func (this *Stmt) InitSRricStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRIC this.s_rric_stmt = new(instruction.SRricStmt) this.s_rric_stmt.Init(op_code, suffix, dc, ra, imm, condition) } func (this *Stmt) InitSRriciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRICI this.s_rrici_stmt = new(instruction.SRriciStmt) this.s_rrici_stmt.Init(op_code, suffix, dc, ra, imm, condition, pc) } func (this *Stmt) InitSRrrStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, ) { this.stmt_type = S_RRR this.s_rrr_stmt = new(instruction.SRrrStmt) this.s_rrr_stmt.Init(op_code, suffix, dc, ra, rb) } func (this *Stmt) InitSRrrcStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRRC this.s_rrrc_stmt = new(instruction.SRrrcStmt) this.s_rrrc_stmt.Init(op_code, suffix, dc, ra, rb, condition) } func (this *Stmt) InitSRrrciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRRCI this.s_rrrci_stmt = new(instruction.SRrrciStmt) this.s_rrrci_stmt.Init(op_code, suffix, dc, ra, rb, condition, pc) } func (this *Stmt) InitSRrriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { this.stmt_type = S_RRRI this.s_rrri_stmt = new(instruction.SRrriStmt) this.s_rrri_stmt.Init(op_code, suffix, dc, ra, rb, imm) } func (this *Stmt) InitSRrriciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRRICI this.s_rrrici_stmt = new(instruction.SRrriciStmt) this.s_rrrici_stmt.Init(op_code, suffix, dc, ra, rb, imm, condition, pc) } func (this *Stmt) InitBkpStmt() { this.stmt_type = BKP this.bkp_stmt = new(sugar.BkpStmt) this.bkp_stmt.Init() } func (this *Stmt) InitBootRiStmt(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr) { this.stmt_type = BOOT_RI this.boot_ri_stmt = new(sugar.BootRiStmt) this.boot_ri_stmt.Init(op_code, ra, imm) } func (this *Stmt) InitCallRiStmt(rc *expr.Expr, imm *expr.Expr) { this.stmt_type = CALL_RI this.call_ri_stmt = new(sugar.CallRiStmt) this.call_ri_stmt.Init(rc, imm) } func (this *Stmt) InitCallRrStmt(rc *expr.Expr, ra *expr.Expr) { this.stmt_type = CALL_RR this.call_rr_stmt = new(sugar.CallRrStmt) this.call_rr_stmt.Init(rc, ra) } func (this *Stmt) InitDivStepDrdiStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, ) { this.stmt_type = DIV_STEP_DRDI this.div_step_drdi_stmt = new(sugar.DivStepDrdiStmt) this.div_step_drdi_stmt.Init(op_code, dc, ra, db, imm) } func (this *Stmt) InitJeqRiiStmt(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, pc *expr.Expr) { this.stmt_type = JEQ_RII this.jeq_rii_stmt = new(sugar.JeqRiiStmt) this.jeq_rii_stmt.Init(op_code, ra, imm, pc) } func (this *Stmt) InitJeqRriStmt(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, pc *expr.Expr) { this.stmt_type = JEQ_RRI this.jeq_rri_stmt = new(sugar.JeqRriStmt) this.jeq_rri_stmt.Init(op_code, ra, rb, pc) } func (this *Stmt) InitJnzRiStmt(op_code *expr.Expr, ra *expr.Expr, pc *expr.Expr) { this.stmt_type = JNZ_RI this.jnz_ri_stmt = new(sugar.JnzRiStmt) this.jnz_ri_stmt.Init(op_code, ra, pc) } func (this *Stmt) InitJumpIStmt(pc *expr.Expr) { this.stmt_type = JUMP_I this.jump_i_stmt = new(sugar.JumpIStmt) this.jump_i_stmt.Init(pc) } func (this *Stmt) InitJumpRStmt(ra *expr.Expr) { this.stmt_type = JUMP_R this.jump_r_stmt = new(sugar.JumpRStmt) this.jump_r_stmt.Init(ra) } func (this *Stmt) InitLbsRriStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr) { this.stmt_type = LBS_RRI this.lbs_rri_stmt = new(sugar.LbsRriStmt) this.lbs_rri_stmt.Init(op_code, rc, ra, off) } func (this *Stmt) InitLbsSRriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = LBS_S_RRI this.lbs_s_rri_stmt = new(sugar.LbsSRriStmt) this.lbs_s_rri_stmt.Init(op_code, suffix, dc, ra, off) } func (this *Stmt) InitLdDriStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = LD_DRI this.ld_dri_stmt = new(sugar.LdDriStmt) this.ld_dri_stmt.Init(op_code, dc, ra, off) } func (this *Stmt) InitMovdDdStmt(op_code *expr.Expr, dc *lexer.Token, db *lexer.Token) { this.stmt_type = MOVD_DD this.movd_dd_stmt = new(sugar.MovdDdStmt) this.movd_dd_stmt.Init(op_code, dc, db) } func (this *Stmt) InitMoveRiStmt(rc *expr.Expr, imm *expr.Expr) { this.stmt_type = MOVE_RI this.move_ri_stmt = new(sugar.MoveRiStmt) this.move_ri_stmt.Init(rc, imm) } func (this *Stmt) InitMoveRiciStmt( rc *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = MOVE_RICI this.move_rici_stmt = new(sugar.MoveRiciStmt) this.move_rici_stmt.Init(rc, imm, condition, pc) } func (this *Stmt) InitMoveSRiStmt(suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr) { this.stmt_type = MOVE_S_RI this.move_s_ri_stmt = new(sugar.MoveSRiStmt) this.move_s_ri_stmt.Init(suffix, dc, imm) } func (this *Stmt) InitMoveSRiciStmt( suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = MOVE_S_RICI this.move_s_rici_stmt = new(sugar.MoveSRiciStmt) this.move_s_rici_stmt.Init(suffix, dc, imm, condition, pc) } func (this *Stmt) InitSbIdRiStmt(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr) { this.stmt_type = SB_ID_RI this.sb_id_ri_stmt = new(sugar.SbIdRiStmt) this.sb_id_ri_stmt.Init(op_code, ra, off) } func (this *Stmt) InitSbIdRiiStmt( op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { this.stmt_type = SB_ID_RII this.sb_id_rii_stmt = new(sugar.SbIdRiiStmt) this.sb_id_rii_stmt.Init(op_code, ra, off, imm) } func (this *Stmt) InitSbRirStmt(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr) { this.stmt_type = SB_RIR this.sb_rir_stmt = new(sugar.SbRirStmt) this.sb_rir_stmt.Init(op_code, ra, off, rb) } func (this *Stmt) InitSdRidStmt( op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { this.stmt_type = SD_RID this.sd_rid_stmt = new(sugar.SdRidStmt) this.sd_rid_stmt.Init(op_code, ra, off, db) } func (this *Stmt) InitStopStmt() { this.stmt_type = STOP this.stop_stmt = new(sugar.StopStmt) this.stop_stmt.Init() } func (this *Stmt) InitTimeCfgRStmt(ra *expr.Expr) { this.stmt_type = TIME_CFG_R this.time_cfg_r_stmt = new(sugar.TimeCfgRStmt) this.time_cfg_r_stmt.Init(ra) } func (this *Stmt) InitLabelStmt(expr_ *expr.Expr) { this.stmt_type = LABEL this.label_stmt = new(LabelStmt) this.label_stmt.Init(expr_) } func (this *Stmt) StmtType() StmtType { return this.stmt_type } func (this *Stmt) AddrsigStmt() *directive.AddrsigStmt { return this.addrsig_stmt } func (this *Stmt) AddrsigSymStmt() *directive.AddrsigSymStmt { return this.addrsig_sym_stmt } func (this *Stmt) AsciiStmt() *directive.AsciiStmt { return this.ascii_stmt } func (this *Stmt) AscizStmt() *directive.AscizStmt { return this.asciz_stmt } func (this *Stmt) ByteStmt() *directive.ByteStmt { return this.byte_stmt } func (this *Stmt) CfiDefCfaOffsetStmt() *directive.CfiDefCfaOffsetStmt { return this.cfi_def_cfa_offset_stmt } func (this *Stmt) CfiEndprocStmt() *directive.CfiEndprocStmt { return this.cfi_endproc_stmt } func (this *Stmt) CfiOffsetStmt() *directive.CfiOffsetStmt { return this.cfi_offset_stmt } func (this *Stmt) CfiSectionsStmt() *directive.CfiSectionsStmt { return this.cfi_sections_stmt } func (this *Stmt) CfiStartprocStmt() *directive.CfiStartprocStmt { return this.cfi_startproc_stmt } func (this *Stmt) FileNumberStmt() *directive.FileNumberStmt { return this.file_number_stmt } func (this *Stmt) FileStringStmt() *directive.FileStringStmt { return this.file_string_stmt } func (this *Stmt) GlobalStmt() *directive.GlobalStmt { return this.global_stmt } func (this *Stmt) LocIsStmtStmt() *directive.LocIsStmtStmt { return this.loc_is_stmt_stmt } func (this *Stmt) LocNumberStmt() *directive.LocNumberStmt { return this.loc_number_stmt } func (this *Stmt) LocPrologueEndStmt() *directive.LocPrologueEndStmt { return this.loc_prologue_end_stmt } func (this *Stmt) LongProgramCounterStmt() *directive.LongProgramCounterStmt { return this.long_program_counter_stmt } func (this *Stmt) LongSectionNameStmt() *directive.LongSectionNameStmt { return this.long_section_name_stmt } func (this *Stmt) P2AlignStmt() *directive.P2AlignStmt { return this.p2_align_stmt } func (this *Stmt) QuadStmt() *directive.QuadStmt { return this.quad_stmt } func (this *Stmt) SectionIdentifierNumberStmt() *directive.SectionIdentifierNumberStmt { return this.section_identifier_number_stmt } func (this *Stmt) SectionIdentifierStmt() *directive.SectionIdentifierStmt { return this.section_identifier_stmt } func (this *Stmt) SectionStackSizesStmt() *directive.SectionStackSizesStmt { return this.section_stack_sizes_stmt } func (this *Stmt) SectionStringNumberStmt() *directive.SectionStringNumberStmt { return this.section_string_number_stmt } func (this *Stmt) SectionStringStmt() *directive.SectionStringStmt { return this.section_string_stmt } func (this *Stmt) SetStmt() *directive.SetStmt { return this.set_stmt } func (this *Stmt) ShortStmt() *directive.ShortStmt { return this.short_stmt } func (this *Stmt) SizeStmt() *directive.SizeStmt { return this.size_stmt } func (this *Stmt) TextStmt() *directive.TextStmt { return this.text_stmt } func (this *Stmt) TypeStmt() *directive.TypeStmt { return this.type_stmt } func (this *Stmt) WeakStmt() *directive.WeakStmt { return this.weak_stmt } func (this *Stmt) ZeroSingleNumberStmt() *directive.ZeroSingleNumberStmt { return this.zero_single_number_stmt } func (this *Stmt) ZeroDoubleNumberStmt() *directive.ZeroDoubleNumberStmt { return this.zero_double_number_stmt } func (this *Stmt) CiStmt() *instruction.CiStmt { return this.ci_stmt } func (this *Stmt) DdciStmt() *instruction.DdciStmt { return this.ddci_stmt } func (this *Stmt) DmaRriStmt() *instruction.DmaRriStmt { return this.dma_rri_stmt } func (this *Stmt) DrdiciStmt() *instruction.DrdiciStmt { return this.drdici_stmt } func (this *Stmt) EdriStmt() *instruction.EdriStmt { return this.edri_stmt } func (this *Stmt) EridStmt() *instruction.EridStmt { return this.erid_stmt } func (this *Stmt) EriiStmt() *instruction.EriiStmt { return this.erii_stmt } func (this *Stmt) ErirStmt() *instruction.ErirStmt { return this.erir_stmt } func (this *Stmt) ErriStmt() *instruction.ErriStmt { return this.erri_stmt } func (this *Stmt) IStmt() *instruction.IStmt { return this.i_stmt } func (this *Stmt) NopStmt() *instruction.NopStmt { return this.nop_stmt } func (this *Stmt) RStmt() *instruction.RStmt { return this.r_stmt } func (this *Stmt) RciStmt() *instruction.RciStmt { return this.rci_stmt } func (this *Stmt) RiciStmt() *instruction.RiciStmt { return this.rici_stmt } func (this *Stmt) RirStmt() *instruction.RirStmt { return this.rir_stmt } func (this *Stmt) RircStmt() *instruction.RircStmt { return this.rirc_stmt } func (this *Stmt) RirciStmt() *instruction.RirciStmt { return this.rirci_stmt } func (this *Stmt) RrStmt() *instruction.RrStmt { return this.rr_stmt } func (this *Stmt) RrcStmt() *instruction.RrcStmt { return this.rrc_stmt } func (this *Stmt) RrciStmt() *instruction.RrciStmt { return this.rrci_stmt } func (this *Stmt) RriStmt() *instruction.RriStmt { return this.rri_stmt } func (this *Stmt) RricStmt() *instruction.RricStmt { return this.rric_stmt } func (this *Stmt) RriciStmt() *instruction.RriciStmt { return this.rrici_stmt } func (this *Stmt) RrrStmt() *instruction.RrrStmt { return this.rrr_stmt } func (this *Stmt) RrrcStmt() *instruction.RrrcStmt { return this.rrrc_stmt } func (this *Stmt) RrrciStmt() *instruction.RrrciStmt { return this.rrrci_stmt } func (this *Stmt) RrriStmt() *instruction.RrriStmt { return this.rrri_stmt } func (this *Stmt) RrriciStmt() *instruction.RrriciStmt { return this.rrrici_stmt } func (this *Stmt) SErriStmt() *instruction.SErriStmt { return this.s_erri_stmt } func (this *Stmt) SRStmt() *instruction.SRStmt { return this.s_r_stmt } func (this *Stmt) SRciStmt() *instruction.SRciStmt { return this.s_rci_stmt } func (this *Stmt) SRircStmt() *instruction.SRircStmt { return this.s_rirc_stmt } func (this *Stmt) SRirciStmt() *instruction.SRirciStmt { return this.s_rirci_stmt } func (this *Stmt) SRrStmt() *instruction.SRrStmt { return this.s_rr_stmt } func (this *Stmt) SRrcStmt() *instruction.SRrcStmt { return this.s_rrc_stmt } func (this *Stmt) SRrciStmt() *instruction.SRrciStmt { return this.s_rrci_stmt } func (this *Stmt) SRriStmt() *instruction.SRriStmt { return this.s_rri_stmt } func (this *Stmt) SRricStmt() *instruction.SRricStmt { return this.s_rric_stmt } func (this *Stmt) SRriciStmt() *instruction.SRriciStmt { return this.s_rrici_stmt } func (this *Stmt) SRrrStmt() *instruction.SRrrStmt { return this.s_rrr_stmt } func (this *Stmt) SRrrcStmt() *instruction.SRrrcStmt { return this.s_rrrc_stmt } func (this *Stmt) SRrrciStmt() *instruction.SRrrciStmt { return this.s_rrrci_stmt } func (this *Stmt) SRrriStmt() *instruction.SRrriStmt { return this.s_rrri_stmt } func (this *Stmt) SRrriciStmt() *instruction.SRrriciStmt { return this.s_rrrici_stmt } func (this *Stmt) BkpStmt() *sugar.BkpStmt { return this.bkp_stmt } func (this *Stmt) BootRiStmt() *sugar.BootRiStmt { return this.boot_ri_stmt } func (this *Stmt) CallRiStmt() *sugar.CallRiStmt { return this.call_ri_stmt } func (this *Stmt) CallRrStmt() *sugar.CallRrStmt { return this.call_rr_stmt } func (this *Stmt) DivStepDrdiStmt() *sugar.DivStepDrdiStmt { return this.div_step_drdi_stmt } func (this *Stmt) JeqRiiStmt() *sugar.JeqRiiStmt { return this.jeq_rii_stmt } func (this *Stmt) JeqRriStmt() *sugar.JeqRriStmt { return this.jeq_rri_stmt } func (this *Stmt) JnzRiStmt() *sugar.JnzRiStmt { return this.jnz_ri_stmt } func (this *Stmt) JumpIStmt() *sugar.JumpIStmt { return this.jump_i_stmt } func (this *Stmt) JumpRStmt() *sugar.JumpRStmt { return this.jump_r_stmt } func (this *Stmt) LbsRriStmt() *sugar.LbsRriStmt { return this.lbs_rri_stmt } func (this *Stmt) LbsSRriStmt() *sugar.LbsSRriStmt { return this.lbs_s_rri_stmt } func (this *Stmt) LdDriStmt() *sugar.LdDriStmt { return this.ld_dri_stmt } func (this *Stmt) MovdDdStmt() *sugar.MovdDdStmt { return this.movd_dd_stmt } func (this *Stmt) MoveRiStmt() *sugar.MoveRiStmt { return this.move_ri_stmt } func (this *Stmt) MoveRiciStmt() *sugar.MoveRiciStmt { return this.move_rici_stmt } func (this *Stmt) MoveSRiStmt() *sugar.MoveSRiStmt { return this.move_s_ri_stmt } func (this *Stmt) MoveSRiciStmt() *sugar.MoveSRiciStmt { return this.move_s_rici_stmt } func (this *Stmt) SbIdRiStmt() *sugar.SbIdRiStmt { return this.sb_id_ri_stmt } func (this *Stmt) SbIdRiiStmt() *sugar.SbIdRiiStmt { return this.sb_id_rii_stmt } func (this *Stmt) SbRirStmt() *sugar.SbRirStmt { return this.sb_rir_stmt } func (this *Stmt) SdRidStmt() *sugar.SdRidStmt { return this.sd_rid_stmt } func (this *Stmt) StopStmt() *sugar.StopStmt { return this.stop_stmt } func (this *Stmt) TimeCfgRStmt() *sugar.TimeCfgRStmt { return this.time_cfg_r_stmt } func (this *Stmt) LabelStmt() *LabelStmt { return this.label_stmt } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/bkp_stmt.go ================================================ package sugar type BkpStmt struct { } func (this *BkpStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/boot_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type BootRiStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr } func (this *BootRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.RICI_OP_CODE { err := errors.New("op code is not an RICI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm } func (this *BootRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *BootRiStmt) Ra() *expr.Expr { return this.ra } func (this *BootRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/call_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CallRiStmt struct { rc *expr.Expr imm *expr.Expr } func (this *CallRiStmt) Init(rc *expr.Expr, imm *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.rc = rc this.imm = imm } func (this *CallRiStmt) Rc() *expr.Expr { return this.rc } func (this *CallRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/call_rr_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type CallRrStmt struct { rc *expr.Expr ra *expr.Expr } func (this *CallRrStmt) Init(rc *expr.Expr, ra *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.rc = rc this.ra = ra } func (this *CallRrStmt) Rc() *expr.Expr { return this.rc } func (this *CallRrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/div_step_drdi_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type DivStepDrdiStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr db *lexer.Token imm *expr.Expr } func (this *DivStepDrdiStmt) Init( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, ) { if op_code.ExprType() != expr.DRDICI_OP_CODE { err := errors.New("op code is not a DRDICI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.db = db this.imm = imm } func (this *DivStepDrdiStmt) OpCode() *expr.Expr { return this.op_code } func (this *DivStepDrdiStmt) Dc() *lexer.Token { return this.dc } func (this *DivStepDrdiStmt) Ra() *expr.Expr { return this.ra } func (this *DivStepDrdiStmt) Db() *lexer.Token { return this.db } func (this *DivStepDrdiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/jeq_rii_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type JeqRiiStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr pc *expr.Expr } func (this *JeqRiiStmt) Init(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm this.pc = pc } func (this *JeqRiiStmt) OpCode() *expr.Expr { return this.op_code } func (this *JeqRiiStmt) Ra() *expr.Expr { return this.ra } func (this *JeqRiiStmt) Imm() *expr.Expr { return this.imm } func (this *JeqRiiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/jeq_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type JeqRriStmt struct { op_code *expr.Expr ra *expr.Expr rb *expr.Expr pc *expr.Expr } func (this *JeqRriStmt) Init(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.rb = rb this.pc = pc } func (this *JeqRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *JeqRriStmt) Ra() *expr.Expr { return this.ra } func (this *JeqRriStmt) Rb() *expr.Expr { return this.rb } func (this *JeqRriStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/jnz_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type JnzRiStmt struct { op_code *expr.Expr ra *expr.Expr pc *expr.Expr } func (this *JnzRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.pc = pc } func (this *JnzRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *JnzRiStmt) Ra() *expr.Expr { return this.ra } func (this *JnzRiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/jump_i_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type JumpIStmt struct { pc *expr.Expr } func (this *JumpIStmt) Init(pc *expr.Expr) { if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.pc = pc } func (this *JumpIStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/jump_r_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type JumpRStmt struct { ra *expr.Expr } func (this *JumpRStmt) Init(ra *expr.Expr) { if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.ra = ra } func (this *JumpRStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/lbs_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type LbsRriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr off *expr.Expr } func (this *LbsRriStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.off = off } func (this *LbsRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LbsRriStmt) Rc() *expr.Expr { return this.rc } func (this *LbsRriStmt) Ra() *expr.Expr { return this.ra } func (this *LbsRriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/lbs_s_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type LbsSRriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *LbsSRriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.off = off } func (this *LbsSRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LbsSRriStmt) Suffix() *expr.Expr { return this.suffix } func (this *LbsSRriStmt) Dc() *lexer.Token { return this.dc } func (this *LbsSRriStmt) Ra() *expr.Expr { return this.ra } func (this *LbsSRriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/ld_dri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type LdDriStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *LdDriStmt) Init(op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.off = off } func (this *LdDriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LdDriStmt) Dc() *lexer.Token { return this.dc } func (this *LdDriStmt) Ra() *expr.Expr { return this.ra } func (this *LdDriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/movd_dd_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type MovdDdStmt struct { op_code *expr.Expr dc *lexer.Token db *lexer.Token } func (this *MovdDdStmt) Init(op_code *expr.Expr, dc *lexer.Token, db *lexer.Token) { if op_code.ExprType() != expr.DDCI_OP_CODE { err := errors.New("op code is not a DDCI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } this.op_code = op_code this.dc = dc this.db = db } func (this *MovdDdStmt) OpCode() *expr.Expr { return this.op_code } func (this *MovdDdStmt) Dc() *lexer.Token { return this.dc } func (this *MovdDdStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/move_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type MoveRiStmt struct { rc *expr.Expr imm *expr.Expr } func (this *MoveRiStmt) Init(rc *expr.Expr, imm *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.rc = rc this.imm = imm } func (this *MoveRiStmt) Rc() *expr.Expr { return this.rc } func (this *MoveRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/move_rici_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type MoveRiciStmt struct { rc *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *MoveRiciStmt) Init(rc *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.rc = rc this.imm = imm this.condition = condition this.pc = pc } func (this *MoveRiciStmt) Rc() *expr.Expr { return this.rc } func (this *MoveRiciStmt) Imm() *expr.Expr { return this.imm } func (this *MoveRiciStmt) Condition() *expr.Expr { return this.condition } func (this *MoveRiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/move_s_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type MoveSRiStmt struct { suffix *expr.Expr dc *lexer.Token imm *expr.Expr } func (this *MoveSRiStmt) Init(suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr) { if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.suffix = suffix this.dc = dc this.imm = imm } func (this *MoveSRiStmt) Suffix() *expr.Expr { return this.suffix } func (this *MoveSRiStmt) Dc() *lexer.Token { return this.dc } func (this *MoveSRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/move_s_rici_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type MoveSRiciStmt struct { suffix *expr.Expr dc *lexer.Token imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *MoveSRiciStmt) Init( suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.suffix = suffix this.dc = dc this.imm = imm this.condition = condition this.pc = pc } func (this *MoveSRiciStmt) Suffix() *expr.Expr { return this.suffix } func (this *MoveSRiciStmt) Dc() *lexer.Token { return this.dc } func (this *MoveSRiciStmt) Imm() *expr.Expr { return this.imm } func (this *MoveSRiciStmt) Condition() *expr.Expr { return this.condition } func (this *MoveSRiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/sb_id_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type SbIdRiStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr } func (this *SbIdRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.off = off } func (this *SbIdRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbIdRiStmt) Ra() *expr.Expr { return this.ra } func (this *SbIdRiStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/sb_id_rii_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type SbIdRiiStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr imm *expr.Expr } func (this *SbIdRiiStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.imm = imm } func (this *SbIdRiiStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbIdRiiStmt) Ra() *expr.Expr { return this.ra } func (this *SbIdRiiStmt) Off() *expr.Expr { return this.off } func (this *SbIdRiiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/sb_rir_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type SbRirStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr rb *expr.Expr } func (this *SbRirStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.rb = rb } func (this *SbRirStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbRirStmt) Ra() *expr.Expr { return this.ra } func (this *SbRirStmt) Off() *expr.Expr { return this.off } func (this *SbRirStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/sd_rid_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/lexer" "uPIMulator/src/linker/parser/expr" ) type SdRidStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr db *lexer.Token } func (this *SdRidStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.db = db } func (this *SdRidStmt) OpCode() *expr.Expr { return this.op_code } func (this *SdRidStmt) Ra() *expr.Expr { return this.ra } func (this *SdRidStmt) Off() *expr.Expr { return this.off } func (this *SdRidStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/stop_stmt.go ================================================ package sugar type StopStmt struct { } func (this *StopStmt) Init() { } ================================================ FILE: golang/uPIMulator/src/linker/parser/stmt/sugar/time_cfg_r_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/linker/parser/expr" ) type TimeCfgRStmt struct { ra *expr.Expr } func (this *TimeCfgRStmt) Init(ra *expr.Expr) { if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.ra = ra } func (this *TimeCfgRStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang/uPIMulator/src/linker/parser/table.go ================================================ package parser import ( "errors" "uPIMulator/src/linker/lexer" ) type Table struct { expr_rules []*Rule stmt_rules []*Rule stack *Stack } func (this *Table) Init(stack *Stack) { this.expr_rules = make([]*Rule, 0) this.stmt_rules = make([]*Rule, 0) this.stack = stack } func (this *Table) AddExprRule(rule *Rule) { this.expr_rules = append(this.expr_rules, rule) } func (this *Table) AddStmtRule(rule *Rule) { this.stmt_rules = append(this.stmt_rules, rule) } func (this *Table) FindReducibleExprRule(token *lexer.Token) (*Rule, []*StackItem) { for num := this.stack.NonStmtSize(); num > 0; num-- { stack_items := this.stack.Front(num) for _, expr_rule := range this.expr_rules { if expr_rule.IsReducible(stack_items, token) { return expr_rule, stack_items } } } return nil, []*StackItem{} } func (this *Table) FindReducibleStmtRule(token *lexer.Token) (*Rule, []*StackItem) { if token.TokenType() != lexer.NEW_LINE { err := errors.New("token is not a new line") panic(err) } num := this.stack.NonStmtSize() stack_items := this.stack.Front(num) for _, stmt_rule := range this.stmt_rules { if stmt_rule.IsReducible(stack_items, token) { return stmt_rule, stack_items } } return nil, []*StackItem{} } ================================================ FILE: golang/uPIMulator/src/linker/parser/walker.go ================================================ package parser import ( "errors" "uPIMulator/src/linker/parser/expr" "uPIMulator/src/linker/parser/stmt" ) type ExprCallback func(*expr.Expr) type StmtCallback func(*stmt.Stmt) type Walker struct { expr_callbacks map[expr.ExprType]ExprCallback stmt_callbacks map[stmt.StmtType]StmtCallback } func (this *Walker) Init() { this.expr_callbacks = make(map[expr.ExprType]ExprCallback, 0) this.stmt_callbacks = make(map[stmt.StmtType]StmtCallback, 0) } func (this *Walker) RegisterExprCallback(expr_type expr.ExprType, expr_callback ExprCallback) { if _, found := this.expr_callbacks[expr_type]; found { err := errors.New("expr callbak is already registered") panic(err) } this.expr_callbacks[expr_type] = expr_callback } func (this *Walker) RegisterStmtCallback(stmt_type stmt.StmtType, stmt_callback StmtCallback) { if _, found := this.stmt_callbacks[stmt_type]; found { err := errors.New("stmt callbak is already registered") panic(err) } this.stmt_callbacks[stmt_type] = stmt_callback } func (this *Walker) Walk(ast *Ast) { for i := 0; i < ast.Size(); i++ { stmt_ := ast.Get(i) stmt_type := stmt_.StmtType() if stmt_type == stmt.ASCII { this.WalkAsciiStmt(stmt_) } else if stmt_type == stmt.ASCIZ { this.WalkAscizStmt(stmt_) } else if stmt_type == stmt.BYTE { this.WalkByteStmt(stmt_) } else if stmt_type == stmt.GLOBAL { this.WalkGlobalStmt(stmt_) } else if stmt_type == stmt.LONG_PROGRAM_COUNTER { this.WalkLongProgramCounterStmt(stmt_) } else if stmt_type == stmt.LONG_SECTION_NAME { this.WalkLongSectionNameStmt(stmt_) } else if stmt_type == stmt.P2_ALIGN { this.WalkP2AlignStmt(stmt_) } else if stmt_type == stmt.QUAD { this.WalkQuadStmt(stmt_) } else if stmt_type == stmt.SECTION_IDENTIFIER_NUMBER { this.WalkSectionIdentifierNumberStmt(stmt_) } else if stmt_type == stmt.SECTION_IDENTIFIER { this.WalkSectionIdentifierStmt(stmt_) } else if stmt_type == stmt.SECTION_STACK_SIZES { this.WalkSectionStackSizesStmt(stmt_) } else if stmt_type == stmt.SECTION_STRING_NUMBER { this.WalkSectionStringNumberStmt(stmt_) } else if stmt_type == stmt.SECTION_STRING { this.WalkSectionStringStmt(stmt_) } else if stmt_type == stmt.SET { this.WalkSetStmt(stmt_) } else if stmt_type == stmt.SHORT { this.WalkShortStmt(stmt_) } else if stmt_type == stmt.SIZE { this.WalkSizeStmt(stmt_) } else if stmt_type == stmt.TEXT { this.WalkTextStmt(stmt_) } else if stmt_type == stmt.ZERO_DOUBLE_NUMBER { this.WalkZeroDoubleNumberStmt(stmt_) } else if stmt_type == stmt.ZERO_SINGLE_NUMBER { this.WalkZeroSingleNumberStmt(stmt_) } else if stmt_type == stmt.CI { this.WalkCiStmt(stmt_) } else if stmt_type == stmt.DDCI { this.WalkDdciStmt(stmt_) } else if stmt_type == stmt.DMA_RRI { this.WalkDmaRriStmt(stmt_) } else if stmt_type == stmt.DRDICI { this.WalkDrdiciStmt(stmt_) } else if stmt_type == stmt.EDRI { this.WalkEdriStmt(stmt_) } else if stmt_type == stmt.ERID { this.WalkEridStmt(stmt_) } else if stmt_type == stmt.ERII { this.WalkEriiStmt(stmt_) } else if stmt_type == stmt.ERIR { this.WalkErirStmt(stmt_) } else if stmt_type == stmt.ERRI { this.WalkErriStmt(stmt_) } else if stmt_type == stmt.I { this.WalkIStmt(stmt_) } else if stmt_type == stmt.NOP { this.WalkNopStmt(stmt_) } else if stmt_type == stmt.RCI { this.WalkRciStmt(stmt_) } else if stmt_type == stmt.RICI { this.WalkRiciStmt(stmt_) } else if stmt_type == stmt.RIRCI { this.WalkRirciStmt(stmt_) } else if stmt_type == stmt.RIRC { this.WalkRircStmt(stmt_) } else if stmt_type == stmt.RIR { this.WalkRirStmt(stmt_) } else if stmt_type == stmt.RRCI { this.WalkRrciStmt(stmt_) } else if stmt_type == stmt.RRC { this.WalkRrcStmt(stmt_) } else if stmt_type == stmt.RRICI { this.WalkRriciStmt(stmt_) } else if stmt_type == stmt.RRIC { this.WalkRricStmt(stmt_) } else if stmt_type == stmt.RRI { this.WalkRriStmt(stmt_) } else if stmt_type == stmt.RRRCI { this.WalkRrrciStmt(stmt_) } else if stmt_type == stmt.RRRC { this.WalkRrrcStmt(stmt_) } else if stmt_type == stmt.RRRICI { this.WalkRrriciStmt(stmt_) } else if stmt_type == stmt.RRRI { this.WalkRrriStmt(stmt_) } else if stmt_type == stmt.RRR { this.WalkRrrStmt(stmt_) } else if stmt_type == stmt.RR { this.WalkRrStmt(stmt_) } else if stmt_type == stmt.R { this.WalkRStmt(stmt_) } else if stmt_type == stmt.S_ERRI { this.WalkSErriStmt(stmt_) } else if stmt_type == stmt.S_RCI { this.WalkSRciStmt(stmt_) } else if stmt_type == stmt.S_RIRCI { this.WalkSRirciStmt(stmt_) } else if stmt_type == stmt.S_RIRC { this.WalkSRircStmt(stmt_) } else if stmt_type == stmt.S_RRCI { this.WalkSRrciStmt(stmt_) } else if stmt_type == stmt.S_RRC { this.WalkSRrcStmt(stmt_) } else if stmt_type == stmt.S_RRICI { this.WalkSRriciStmt(stmt_) } else if stmt_type == stmt.S_RRIC { this.WalkSRricStmt(stmt_) } else if stmt_type == stmt.S_RRI { this.WalkSRriStmt(stmt_) } else if stmt_type == stmt.S_RRRCI { this.WalkSRrrciStmt(stmt_) } else if stmt_type == stmt.S_RRRC { this.WalkSRrrcStmt(stmt_) } else if stmt_type == stmt.S_RRRICI { this.WalkSRrriciStmt(stmt_) } else if stmt_type == stmt.S_RRRI { this.WalkSRrriStmt(stmt_) } else if stmt_type == stmt.S_RRR { this.WalkSRrrStmt(stmt_) } else if stmt_type == stmt.S_RR { this.WalkSRrStmt(stmt_) } else if stmt_type == stmt.S_R { this.WalkSRStmt(stmt_) } else if stmt_type == stmt.BKP { this.WalkBkpStmt(stmt_) } else if stmt_type == stmt.BOOT_RI { this.WalkBootRiStmt(stmt_) } else if stmt_type == stmt.CALL_RI { this.WalkCallRiStmt(stmt_) } else if stmt_type == stmt.CALL_RR { this.WalkCallRrStmt(stmt_) } else if stmt_type == stmt.DIV_STEP_DRDI { this.WalkDivStepDrdiStmt(stmt_) } else if stmt_type == stmt.JEQ_RII { this.WalkJeqRiiStmt(stmt_) } else if stmt_type == stmt.JEQ_RRI { this.WalkJeqRriStmt(stmt_) } else if stmt_type == stmt.JNZ_RI { this.WalkJnzRiStmt(stmt_) } else if stmt_type == stmt.JUMP_I { this.WalkJumpIStmt(stmt_) } else if stmt_type == stmt.JUMP_R { this.WalkJumpRStmt(stmt_) } else if stmt_type == stmt.LBS_RRI { this.WalkLbsRriStmt(stmt_) } else if stmt_type == stmt.LBS_S_RRI { this.WalkLbsSRriStmt(stmt_) } else if stmt_type == stmt.LD_DRI { this.WalkLdDriStmt(stmt_) } else if stmt_type == stmt.MOVD_DD { this.WalkMovdDdStmt(stmt_) } else if stmt_type == stmt.MOVE_RICI { this.WalkMoveRiciStmt(stmt_) } else if stmt_type == stmt.MOVE_RI { this.WalkMoveRiStmt(stmt_) } else if stmt_type == stmt.MOVE_S_RICI { this.WalkMoveSRiciStmt(stmt_) } else if stmt_type == stmt.MOVE_S_RI { this.WalkMoveSRiStmt(stmt_) } else if stmt_type == stmt.SB_ID_RII { this.WalkSbIdRiiStmt(stmt_) } else if stmt_type == stmt.SB_ID_RI { this.WalkSbIdRiStmt(stmt_) } else if stmt_type == stmt.SB_RIR { this.WalkSbRirStmt(stmt_) } else if stmt_type == stmt.SD_RID { this.WalkSdRidStmt(stmt_) } else if stmt_type == stmt.STOP { this.WalkStopStmt(stmt_) } else if stmt_type == stmt.TIME_CFG_R { this.WalkTimeCfgRStmt(stmt_) } else if stmt_type == stmt.LABEL { this.WalkLabelStmt(stmt_) } else { continue } } } func (this *Walker) WalkBinaryAddExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.BINARY_ADD { err := errors.New("expr type is not binary add expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.BINARY_ADD]; found { expr_callback(expr_) } binary_add_expr := expr_.BinaryAddExpr() operand1 := binary_add_expr.Operand1() operand2 := binary_add_expr.Operand2() this.WalkPrimaryExpr(operand1) this.WalkPrimaryExpr(operand2) } func (this *Walker) WalkBinarySubExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.BINARY_SUB { err := errors.New("expr type is not binary sub expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.BINARY_SUB]; found { expr_callback(expr_) } binary_sub_expr := expr_.BinarySubExpr() operand1 := binary_sub_expr.Operand1() operand2 := binary_sub_expr.Operand2() this.WalkPrimaryExpr(operand1) this.WalkPrimaryExpr(operand2) } func (this *Walker) WalkNegativeNumberExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.NEGATIVE_NUMBER { err := errors.New("expr type is not negative number expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.NEGATIVE_NUMBER]; found { expr_callback(expr_) } } func (this *Walker) WalkPrimaryExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PRIMARY { err := errors.New("expr type is not primary") panic(err) } if expr_callback, found := this.expr_callbacks[expr.PRIMARY]; found { expr_callback(expr_) } } func (this *Walker) WalkProgramCounterExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr type is not program counter expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.PROGRAM_COUNTER]; found { expr_callback(expr_) } program_counter_expr := expr_.ProgramCounterExpr() child_expr := program_counter_expr.Expr() child_expr_type := child_expr.ExprType() if child_expr_type == expr.PRIMARY { this.WalkPrimaryExpr(child_expr) } else if child_expr_type == expr.NEGATIVE_NUMBER { this.WalkNegativeNumberExpr(child_expr) } else if child_expr_type == expr.BINARY_ADD { this.WalkBinaryAddExpr(child_expr) } else if child_expr_type == expr.BINARY_SUB { this.WalkBinarySubExpr(child_expr) } else { err := errors.New("child expr is not valid for a program counter expr") panic(err) } } func (this *Walker) WalkAsciiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ASCII { err := errors.New("stmt type is not an ASCII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ASCII]; found { stmt_callback(stmt_) } } func (this *Walker) WalkAscizStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ASCIZ { err := errors.New("stmt type is not an ASCIZ stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ASCIZ]; found { stmt_callback(stmt_) } } func (this *Walker) WalkByteStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BYTE { err := errors.New("stmt type is not a byte stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BYTE]; found { stmt_callback(stmt_) } byte_stmt := stmt_.ByteStmt() expr_ := byte_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkGlobalStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.GLOBAL { err := errors.New("stmt type is not a global stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.GLOBAL]; found { stmt_callback(stmt_) } global_stmt := stmt_.GlobalStmt() expr_ := global_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LONG_PROGRAM_COUNTER { err := errors.New("stmt type is not a long program counter stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LONG_PROGRAM_COUNTER]; found { stmt_callback(stmt_) } long_program_counter_stmt := stmt_.LongProgramCounterStmt() expr_ := long_program_counter_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LONG_SECTION_NAME { err := errors.New("stmt type is not a long section name stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LONG_SECTION_NAME]; found { stmt_callback(stmt_) } } func (this *Walker) WalkP2AlignStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.P2_ALIGN { err := errors.New("stmt type is not a p2align stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.P2_ALIGN]; found { stmt_callback(stmt_) } } func (this *Walker) WalkQuadStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.QUAD { err := errors.New("stmt type is not a quad stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.QUAD]; found { stmt_callback(stmt_) } quad_stmt := stmt_.QuadStmt() expr_ := quad_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_IDENTIFIER_NUMBER { err := errors.New("stmt type is not a section identifier number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_IDENTIFIER_NUMBER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_IDENTIFIER { err := errors.New("stmt type is not a section identifier stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_IDENTIFIER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStackSizesStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STACK_SIZES { err := errors.New("stmt type is not a section stack sizes stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STACK_SIZES]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STRING_NUMBER { err := errors.New("stmt type is not a section string number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STRING_NUMBER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStringStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STRING { err := errors.New("stmt type is not a section string stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STRING]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSetStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SET { err := errors.New("stmt type is not a set stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SET]; found { stmt_callback(stmt_) } set_stmt := stmt_.SetStmt() expr1 := set_stmt.Expr1() expr2 := set_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkShortStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SHORT { err := errors.New("stmt type is not a short stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SHORT]; found { stmt_callback(stmt_) } short_stmt := stmt_.ShortStmt() expr_ := short_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkSizeStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SIZE { err := errors.New("stmt type is not a size stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SIZE]; found { stmt_callback(stmt_) } size_stmt := stmt_.SizeStmt() expr1 := size_stmt.Expr1() expr2 := size_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkTextStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.TEXT { err := errors.New("stmt type is not a text stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.TEXT]; found { stmt_callback(stmt_) } } func (this *Walker) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ZERO_DOUBLE_NUMBER { err := errors.New("stmt type is not a zero double number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ZERO_DOUBLE_NUMBER]; found { stmt_callback(stmt_) } zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() expr1 := zero_double_number_stmt.Expr1() expr2 := zero_double_number_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ZERO_SINGLE_NUMBER { err := errors.New("stmt type is not a zero single number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ZERO_SINGLE_NUMBER]; found { stmt_callback(stmt_) } zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() expr_ := zero_single_number_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkCiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CI { err := errors.New("stmt type is not a CI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CI]; found { stmt_callback(stmt_) } ci_stmt := stmt_.CiStmt() pc := ci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkDdciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DDCI { err := errors.New("stmt type is not a DDCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DDCI]; found { stmt_callback(stmt_) } ddci_stmt := stmt_.DdciStmt() pc := ddci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkDmaRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DMA_RRI { err := errors.New("stmt type is not a DMA_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DMA_RRI]; found { stmt_callback(stmt_) } dma_rri_stmt := stmt_.DmaRriStmt() imm := dma_rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkDrdiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DRDICI { err := errors.New("stmt type is not a DRDICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DRDICI]; found { stmt_callback(stmt_) } drdici_stmt := stmt_.DrdiciStmt() imm := drdici_stmt.Imm() pc := drdici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkEdriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.EDRI { err := errors.New("stmt type is not an EDRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.EDRI]; found { stmt_callback(stmt_) } edri_stmt := stmt_.EdriStmt() off := edri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkEridStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERID { err := errors.New("stmt type is not an ERID stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERID]; found { stmt_callback(stmt_) } erid_stmt := stmt_.EridStmt() off := erid_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkEriiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERII { err := errors.New("stmt type is not an ERII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERII]; found { stmt_callback(stmt_) } erii_stmt := stmt_.EriiStmt() off := erii_stmt.Off() imm := erii_stmt.Imm() this.WalkProgramCounterExpr(off) this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkErirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERIR { err := errors.New("stmt type is not an ERIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERIR]; found { stmt_callback(stmt_) } erir_stmt := stmt_.ErirStmt() off := erir_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkErriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERRI { err := errors.New("stmt type is not an ERRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERRI]; found { stmt_callback(stmt_) } erri_stmt := stmt_.ErriStmt() off := erri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkIStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.I { err := errors.New("stmt type is not an I stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.I]; found { stmt_callback(stmt_) } i_stmt := stmt_.IStmt() imm := i_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkNopStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.NOP { err := errors.New("stmt type is not a NOP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.NOP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RCI { err := errors.New("stmt type is not an RCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RCI]; found { stmt_callback(stmt_) } rci_stmt := stmt_.RciStmt() pc := rci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RICI { err := errors.New("stmt type is not an RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RICI]; found { stmt_callback(stmt_) } rici_stmt := stmt_.RiciStmt() imm := rici_stmt.Imm() pc := rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRirciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIRCI { err := errors.New("stmt type is not an RIRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIRCI]; found { stmt_callback(stmt_) } rirci_stmt := stmt_.RirciStmt() imm := rirci_stmt.Imm() pc := rirci_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRircStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIRC { err := errors.New("stmt type is not an RIRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIRC]; found { stmt_callback(stmt_) } rirc_stmt := stmt_.RircStmt() imm := rirc_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIR { err := errors.New("stmt type is not an RIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIR]; found { stmt_callback(stmt_) } rir_stmt := stmt_.RirStmt() imm := rir_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRCI { err := errors.New("stmt type is not an RRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRCI]; found { stmt_callback(stmt_) } rrci_stmt := stmt_.RrciStmt() pc := rrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRC { err := errors.New("stmt type is not an RRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRICI { err := errors.New("stmt type is not an RRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRICI]; found { stmt_callback(stmt_) } rrici_stmt := stmt_.RriciStmt() imm := rrici_stmt.Imm() pc := rrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRricStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRIC { err := errors.New("stmt type is not an RRIC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRIC]; found { stmt_callback(stmt_) } rric_stmt := stmt_.RricStmt() imm := rric_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRI { err := errors.New("stmt type is not an RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRI]; found { stmt_callback(stmt_) } rri_stmt := stmt_.RriStmt() imm := rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRCI { err := errors.New("stmt type is not an RRRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRCI]; found { stmt_callback(stmt_) } rrrci_stmt := stmt_.RrrciStmt() pc := rrrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRC { err := errors.New("stmt type is not an RRRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRrriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRICI { err := errors.New("stmt type is not an RRRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRICI]; found { stmt_callback(stmt_) } rrrici_stmt := stmt_.RrriciStmt() imm := rrrici_stmt.Imm() pc := rrrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRI { err := errors.New("stmt type is not an RRRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRI]; found { stmt_callback(stmt_) } rrri_stmt := stmt_.RrriStmt() imm := rrri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRR { err := errors.New("stmt type is not an RRR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RR { err := errors.New("stmt type is not an RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.R { err := errors.New("stmt type is not an R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSErriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_ERRI { err := errors.New("stmt type is not a S_ERRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_ERRI]; found { stmt_callback(stmt_) } s_erri_stmt := stmt_.SErriStmt() off := s_erri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSRciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RCI { err := errors.New("stmt type is not a S_RCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RCI]; found { stmt_callback(stmt_) } s_rci_stmt := stmt_.SRciStmt() pc := s_rci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRirciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RIRCI { err := errors.New("stmt type is not a S_RIRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RIRCI]; found { stmt_callback(stmt_) } s_rirci_stmt := stmt_.SRirciStmt() imm := s_rirci_stmt.Imm() pc := s_rirci_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRircStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RIRC { err := errors.New("stmt type is not a S_RIRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RIRC]; found { stmt_callback(stmt_) } s_rirc_stmt := stmt_.SRircStmt() imm := s_rirc_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRCI { err := errors.New("stmt type is not a S_RRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRCI]; found { stmt_callback(stmt_) } s_rrci_stmt := stmt_.SRrciStmt() pc := s_rrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRC { err := errors.New("stmt type is not a S_RRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRICI { err := errors.New("stmt type is not a S_RRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRICI]; found { stmt_callback(stmt_) } s_rrici_stmt := stmt_.SRriciStmt() imm := s_rrici_stmt.Imm() pc := s_rrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRricStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRIC { err := errors.New("stmt type is not a S_RRIC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRIC]; found { stmt_callback(stmt_) } s_rric_stmt := stmt_.SRricStmt() imm := s_rric_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRI { err := errors.New("stmt type is not a S_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRI]; found { stmt_callback(stmt_) } s_rri_stmt := stmt_.SRriStmt() imm := s_rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRCI { err := errors.New("stmt type is not an S_RRRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRCI]; found { stmt_callback(stmt_) } s_rrrci_stmt := stmt_.SRrrciStmt() pc := s_rrrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRC { err := errors.New("stmt type is not an S_RRRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRrriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRICI { err := errors.New("stmt type is not a S_RRRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRICI]; found { stmt_callback(stmt_) } s_rrrici_stmt := stmt_.SRrriciStmt() imm := s_rrrici_stmt.Imm() pc := s_rrrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRI { err := errors.New("stmt type is not a S_RRRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRI]; found { stmt_callback(stmt_) } s_rrri_stmt := stmt_.SRrriStmt() imm := s_rrri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRR { err := errors.New("stmt type is not a RRR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RR { err := errors.New("stmt type is not a S_RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_R { err := errors.New("stmt type is not a S_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkBkpStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BKP { err := errors.New("stmt type is not a BKP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BKP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkBootRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BOOT_RI { err := errors.New("stmt type is not a BOOT_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BOOT_RI]; found { stmt_callback(stmt_) } boot_ri_stmt := stmt_.BootRiStmt() imm := boot_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkCallRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CALL_RI { err := errors.New("stmt type is not a CALL_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CALL_RI]; found { stmt_callback(stmt_) } call_ri_stmt := stmt_.CallRiStmt() imm := call_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkCallRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CALL_RR { err := errors.New("stmt type is not a CALL_RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CALL_RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkDivStepDrdiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DIV_STEP_DRDI { err := errors.New("stmt type is not a DIV_STEP_DRDI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DIV_STEP_DRDI]; found { stmt_callback(stmt_) } div_step_drdi_stmt := stmt_.DivStepDrdiStmt() imm := div_step_drdi_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkJeqRiiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JEQ_RII { err := errors.New("stmt type is not a JEQ_RII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JEQ_RII]; found { stmt_callback(stmt_) } jeq_rii_stmt := stmt_.JeqRiiStmt() imm := jeq_rii_stmt.Imm() pc := jeq_rii_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJeqRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JEQ_RRI { err := errors.New("stmt type is not a JEQ_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JEQ_RRI]; found { stmt_callback(stmt_) } jeq_rri_stmt := stmt_.JeqRriStmt() pc := jeq_rri_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJnzRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JNZ_RI { err := errors.New("stmt type is not a JNZ_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JNZ_RI]; found { stmt_callback(stmt_) } jnz_ri_stmt := stmt_.JnzRiStmt() pc := jnz_ri_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJumpIStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JUMP_I { err := errors.New("stmt type is not a JUMP_I stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JUMP_I]; found { stmt_callback(stmt_) } jump_i_stmt := stmt_.JumpIStmt() pc := jump_i_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJumpRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JUMP_R { err := errors.New("stmt type is not a JUMP_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JUMP_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkLbsRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LBS_RRI { err := errors.New("stmt type is not a LBS_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LBS_RRI]; found { stmt_callback(stmt_) } lbs_rri_stmt := stmt_.LbsRriStmt() off := lbs_rri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkLbsSRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LBS_S_RRI { err := errors.New("stmt type is not a LBS_S_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LBS_S_RRI]; found { stmt_callback(stmt_) } lbs_s_rri_stmt := stmt_.LbsSRriStmt() off := lbs_s_rri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkLdDriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LD_DRI { err := errors.New("stmt type is not a LD_DRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LD_DRI]; found { stmt_callback(stmt_) } ld_dri_stmt := stmt_.LdDriStmt() off := ld_dri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkMovdDdStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVD_DD { err := errors.New("stmt type is not a MOVD_DD stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVD_DD]; found { stmt_callback(stmt_) } } func (this *Walker) WalkMoveRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_RICI { err := errors.New("stmt type is not a MOVE_RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_RICI]; found { stmt_callback(stmt_) } move_rici_stmt := stmt_.MoveRiciStmt() imm := move_rici_stmt.Imm() pc := move_rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkMoveRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_RI { err := errors.New("stmt type is not a MOVE_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_RI]; found { stmt_callback(stmt_) } move_ri_stmt := stmt_.MoveRiStmt() imm := move_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkMoveSRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_S_RICI { err := errors.New("stmt type is not a MOVE_S_RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_S_RICI]; found { stmt_callback(stmt_) } move_s_rici_stmt := stmt_.MoveSRiciStmt() imm := move_s_rici_stmt.Imm() pc := move_s_rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkMoveSRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_S_RI { err := errors.New("stmt type is not a MOVE_S_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_S_RI]; found { stmt_callback(stmt_) } move_s_ri_stmt := stmt_.MoveSRiStmt() imm := move_s_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSbIdRiiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_ID_RII { err := errors.New("stmt type is not a SB_ID_RII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_ID_RII]; found { stmt_callback(stmt_) } sb_id_rii_stmt := stmt_.SbIdRiiStmt() off := sb_id_rii_stmt.Off() imm := sb_id_rii_stmt.Imm() this.WalkProgramCounterExpr(off) this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSbIdRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_ID_RI { err := errors.New("stmt type is not a SB_ID_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_ID_RI]; found { stmt_callback(stmt_) } sb_id_ri_stmt := stmt_.SbIdRiStmt() off := sb_id_ri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSbRirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_RIR { err := errors.New("stmt type is not a SB_RIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_RIR]; found { stmt_callback(stmt_) } sb_rir_stmt := stmt_.SbRirStmt() off := sb_rir_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSdRidStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SD_RID { err := errors.New("stmt type is not a SD_RID stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SD_RID]; found { stmt_callback(stmt_) } sd_rid_stmt := stmt_.SdRidStmt() off := sd_rid_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkStopStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.STOP { err := errors.New("stmt type is not a STOP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.STOP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkTimeCfgRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.TIME_CFG_R { err := errors.New("stmt type is not a TIME_CFG_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.TIME_CFG_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkLabelStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LABEL { err := errors.New("stmt type is not a LABEL stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LABEL]; found { stmt_callback(stmt_) } label_stmt := stmt_.LabelStmt() expr_ := label_stmt.Expr() this.WalkProgramCounterExpr(expr_) } ================================================ FILE: golang/uPIMulator/src/main.go ================================================ package main import ( "fmt" "os" "path/filepath" "uPIMulator/src/assembler" "uPIMulator/src/compiler" "uPIMulator/src/linker" "uPIMulator/src/misc" "uPIMulator/src/simulator" ) func main() { command_line_parser := InitCommandLineParser() command_line_parser.Parse(os.Args) if command_line_parser.IsArgSet("help") { fmt.Printf("%s", command_line_parser.StringifyHelpMsgs()) } else { command_line_validator := new(misc.CommandLineValidator) command_line_validator.Init(command_line_parser) command_line_validator.Validate() config_loader := new(misc.ConfigLoader) config_loader.Init() config_validator := new(misc.ConfigValidator) config_validator.Init(config_loader) config_validator.Validate() bin_dirpath := command_line_parser.StringParameter("bin_dirpath") args_filepath := filepath.Join(bin_dirpath, "args.txt") options_filepath := filepath.Join(bin_dirpath, "options.txt") args_file_dumper := new(misc.FileDumper) args_file_dumper.Init(args_filepath) args_file_dumper.WriteLines([]string{command_line_parser.StringifyArgs()}) options_file_dumper := new(misc.FileDumper) options_file_dumper.Init(options_filepath) options_file_dumper.WriteLines([]string{command_line_parser.StringifyOptions()}) compiler_ := new(compiler.Compiler) compiler_.Init(command_line_parser) compiler_.Compile() linker_ := new(linker.Linker) linker_.Init(command_line_parser) linker_.Link() assembler_ := new(assembler.Assembler) assembler_.Init(command_line_parser) assembler_.Assemble() simulator_ := new(simulator.Simulator) simulator_.Init(command_line_parser) for !simulator_.IsFinished() { simulator_.Cycle() } simulator_.Dump() simulator_.Fini() } } func InitCommandLineParser() *misc.CommandLineParser { command_line_parser := new(misc.CommandLineParser) command_line_parser.Init() // NOTE(dongjae.lee@kaist.ac.kr): Explanation of verbose level // level 0: Only prints simulation output // level 1: level 0 + prints UPMEM instruction executed per each logic cycle // level 2: level + prints UPMEM register file values per each logic cycle command_line_parser.AddOption(misc.INT, "verbose", "0", "verbosity of the simulation") command_line_parser.AddOption(misc.INT, "num_simulation_threads", "16", "number of simulation threads to launch") command_line_parser.AddOption(misc.STRING, "benchmark", "BS", "benchmark name") command_line_parser.AddOption(misc.INT, "num_channels", "1", "number of PIM memory channels") command_line_parser.AddOption( misc.INT, "num_ranks_per_channel", "1", "number of ranks per channel", ) command_line_parser.AddOption(misc.INT, "num_dpus_per_rank", "1", "number of DPUs per rank") command_line_parser.AddOption(misc.INT, "num_tasklets", "1", "number of tasklets") command_line_parser.AddOption(misc.STRING, "data_prep_params", "8192", "data preparation parameter") command_line_parser.AddOption( misc.STRING, "root_dirpath", "/home/via/uPIMulator/golang/uPIMulator", "path to the root directory", ) command_line_parser.AddOption(misc.STRING, "bin_dirpath", "/home/via/uPIMulator/golang/uPIMulator/bin", "path to the bin directory") command_line_parser.AddOption(misc.STRING, "log_dirpath", "/home/via/uPIMulator/golang/log", "path to the log directory") command_line_parser.AddOption(misc.INT, "logic_frequency", "350", "DPU logic frequency in MHz") command_line_parser.AddOption(misc.INT, "memory_frequency", "2400", "DPU MRAM frequency in MHz") command_line_parser.AddOption(misc.INT, "num_pipeline_stages", "14", "number of DPU logic pipeline stages") command_line_parser.AddOption(misc.INT, "num_revolver_scheduling_cycles", "11", "number of DPU logic revolver scheduling cycles") command_line_parser.AddOption(misc.INT, "wordline_size", "1024", "row buffer size per single DPU's MRAM in bytes") command_line_parser.AddOption(misc.INT, "min_access_granularity", "8", "DPU MRAM's minimum access granularity in bytes") command_line_parser.AddOption( misc.INT, "t_rcd", "32", "DPU MRAM t_rcd timing parameter [cycle]", ) command_line_parser.AddOption( misc.INT, "t_ras", "78", "DPU MRAM t_ras timing parameter [cycle]", ) command_line_parser.AddOption(misc.INT, "t_rp", "32", "DPU MRAM t_rp timing parameter [cycle]") command_line_parser.AddOption(misc.INT, "t_cl", "32", "DPU MRAM t_cl timing parameter [cycle]") command_line_parser.AddOption(misc.INT, "t_bl", "8", "DPU MRAM t_bl timing parameter [cycle]") command_line_parser.AddOption( misc.INT, "read_bandwidth", "1", "read bandwidth per DPU per rank [bytes/cycle]", ) command_line_parser.AddOption( misc.INT, "write_bandwidth", "3", "write bandwidth per DPU per rank [bytes/cycle]", ) return command_line_parser } ================================================ FILE: golang/uPIMulator/src/misc/command_line_option.go ================================================ package misc import ( "errors" "fmt" "strconv" ) type CommandLineOptionType int const ( BOOL = iota INT STRING ) type CommandLineOption struct { command_line_option_type CommandLineOptionType option string default_parameter string custom_parameter string help_msg string } func (this *CommandLineOption) Init( command_line_option_type CommandLineOptionType, option string, default_parameter string, help_msg string, ) { this.command_line_option_type = command_line_option_type this.option = option this.default_parameter = default_parameter this.custom_parameter = "" this.help_msg = help_msg } func (this *CommandLineOption) CommandLineOptionType() CommandLineOptionType { return this.command_line_option_type } func (this *CommandLineOption) Option() string { return this.option } func (this *CommandLineOption) Parameter() string { if this.custom_parameter == "" { return this.default_parameter } else { return this.custom_parameter } } func (this *CommandLineOption) HelpMsg() string { return this.help_msg } func (this *CommandLineOption) SetCustomParameter(custom_parameter string) { if this.custom_parameter != "" { err := errors.New("custom parameter is already set") panic(err) } this.custom_parameter = custom_parameter } func (this *CommandLineOption) BoolParameter() bool { if this.Parameter() == "true" { return true } else if this.Parameter() == "false" { return false } else { err_msg := fmt.Sprintf("parameter (%s) is not true or false", this.Parameter()) err := errors.New(err_msg) panic(err) } } func (this *CommandLineOption) IntParameter() int64 { int_parameter, err := strconv.ParseInt(this.Parameter(), 10, 64) if err != nil { panic(err) } return int_parameter } func (this *CommandLineOption) StringParameter() string { return this.Parameter() } ================================================ FILE: golang/uPIMulator/src/misc/command_line_parser.go ================================================ package misc import ( "errors" "fmt" "slices" "strconv" "strings" ) type CommandLineParser struct { command_line_options map[string]*CommandLineOption args map[string]bool } func (this *CommandLineParser) Init() { this.command_line_options = make(map[string]*CommandLineOption, 0) this.args = make(map[string]bool, 0) } func (this *CommandLineParser) AddOption( command_line_option_type CommandLineOptionType, option string, default_parameter string, help_msg string, ) { if _, found := this.command_line_options[option]; found { err_msg := fmt.Sprintf("option (%s) is already added to the parser") err := errors.New(err_msg) panic(err) } command_line_option := new(CommandLineOption) command_line_option.Init(command_line_option_type, option, default_parameter, help_msg) this.command_line_options[option] = command_line_option } func (this *CommandLineParser) Parse(os_args []string) { for i := 1; i < len(os_args); i++ { os_arg := os_args[i] if os_arg[0:2] == "--" { option := os_arg[2:] custom_parameter := os_args[i+1] this.command_line_options[option].SetCustomParameter(custom_parameter) i++ } else if os_arg[0:1] == "-" { arg := os_arg[1:] if _, found := this.args[arg]; found { err_msg := fmt.Sprintf("arg (%s) is already set", arg) err := errors.New(err_msg) panic(err) } this.args[arg] = true } else { err := errors.New("command line options are corrupted") panic(err) } } } func (this *CommandLineParser) BoolParameter(option string) bool { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.BoolParameter() } func (this *CommandLineParser) IntParameter(option string) int64 { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.IntParameter() } func (this *CommandLineParser) StringParameter(option string) string { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.StringParameter() } func (this *CommandLineParser) DataPrepParams() []int { string_params := strings.Split(this.StringParameter("data_prep_params"), ",") data_prep_params := make([]int, 0) for _, string_param := range string_params { int_param, err := strconv.Atoi(string_param) if err != nil { panic(err) } data_prep_params = append(data_prep_params, int_param) } return data_prep_params } func (this *CommandLineParser) IsArgSet(arg string) bool { if _, found := this.args[arg]; found { return true } else { return false } } func (this *CommandLineParser) Options() []string { options := make([]string, 0) for option := range this.command_line_options { options = append(options, option) } slices.Sort(options) return options } func (this *CommandLineParser) Args() []string { args := make([]string, 0) for arg := range this.args { args = append(args, arg) } slices.Sort(args) return args } func (this *CommandLineParser) StringifyOptions() string { str := "OPTIONS\n" for option, command_line_option := range this.command_line_options { str += option + " --> " + command_line_option.Parameter() + "\n" } return str } func (this *CommandLineParser) StringifyArgs() string { str := "ARGS\n" for arg := range this.args { str += arg + "\n" } return str } func (this *CommandLineParser) StringifyHelpMsgs() string { str := "HELP_MSGS\n" for option, command_line_option := range this.command_line_options { str += option + " --> " + command_line_option.HelpMsg() + "\n" } return str } ================================================ FILE: golang/uPIMulator/src/misc/command_line_validator.go ================================================ package misc import ( "errors" "fmt" "os" ) type CommandLineValidator struct { command_line_parser *CommandLineParser } func (this *CommandLineValidator) Init(command_line_parser *CommandLineParser) { this.command_line_parser = command_line_parser } func (this *CommandLineValidator) Validate() { if this.command_line_parser.IntParameter("num_simulation_threads") <= 0 { err := errors.New("num_simulation_threads <= 0") panic(err) } if this.command_line_parser.IntParameter("num_channels") <= 0 { err := errors.New("num_channels <= 0") panic(err) } if this.command_line_parser.IntParameter("num_ranks_per_channel") <= 0 { err := errors.New("num_ranks <= 0") panic(err) } if this.command_line_parser.IntParameter("num_dpus_per_rank") <= 0 { err := errors.New("num_dpus <= 0") panic(err) } if this.command_line_parser.IntParameter("num_tasklets") <= 0 { err := errors.New("num_tasklets <= 0") panic(err) } if _, stat_err := os.Stat(this.command_line_parser.StringParameter("root_dirpath")); os.IsNotExist( stat_err, ) { fmt.Println(this.command_line_parser.StringParameter("root_dirpath")) err := errors.New("root_dirpath does not exist") panic(err) } if this.command_line_parser.IntParameter("logic_frequency") <= 0 { err := errors.New("logic_frequency <= 0") panic(err) } if this.command_line_parser.IntParameter("memory_frequency") <= 0 { err := errors.New("memory_frequency <= 0") panic(err) } if this.command_line_parser.IntParameter("num_pipeline_stages") <= 0 { err := errors.New("num_pipeline_stages <= 0") panic(err) } if this.command_line_parser.IntParameter("num_revolver_scheduling_cycles") < 0 { err := errors.New("num_revolver_scheduling_cycles < 0") panic(err) } if this.command_line_parser.IntParameter("wordline_size") <= 0 { err := errors.New("wordline_size <= 0") panic(err) } if this.command_line_parser.IntParameter("min_access_granularity") <= 0 { err := errors.New("min_access_granularity <= 0") panic(err) } if this.command_line_parser.IntParameter("min_access_granularity") <= 0 { err := errors.New("min_access_granularity <= 0") panic(err) } if this.command_line_parser.IntParameter("t_rcd") < 0 { err := errors.New("t_rcd < 0") panic(err) } if this.command_line_parser.IntParameter("t_ras") < 0 { err := errors.New("t_ras < 0") panic(err) } if this.command_line_parser.IntParameter("t_rp") < 0 { err := errors.New("t_rp < 0") panic(err) } if this.command_line_parser.IntParameter("t_cl") < 0 { err := errors.New("t_cl < 0") panic(err) } if this.command_line_parser.IntParameter("t_bl") < 0 { err := errors.New("t_bl < 0") panic(err) } if this.command_line_parser.IntParameter("read_bandwidth") <= 0 { err := errors.New("read_bandwidth <= 0") panic(err) } if this.command_line_parser.IntParameter("write_bandwidth") <= 0 { err := errors.New("write_bandwidth <= 0") panic(err) } } ================================================ FILE: golang/uPIMulator/src/misc/config_loader.go ================================================ package misc type ConfigLoader struct { } func (this *ConfigLoader) Init() { } func (this *ConfigLoader) AddressWidth() int { return 32 } func (this *ConfigLoader) AtomicDataWidth() int { return 32 } func (this *ConfigLoader) AtomicOffset() int64 { return 0 } func (this *ConfigLoader) AtomicSize() int64 { return 256 } func (this *ConfigLoader) IramDataWidth() int { return 96 } func (this *ConfigLoader) IramOffset() int64 { return 384 * 1024 } func (this *ConfigLoader) IramSize() int64 { return 48 * 1024 } func (this *ConfigLoader) WramDataWidth() int { return 32 } func (this *ConfigLoader) WramOffset() int64 { return 512 } func (this *ConfigLoader) WramSize() int64 { return 128 * 1024 } func (this *ConfigLoader) MramDataWidth() int { return 32 } func (this *ConfigLoader) MramOffset() int64 { return 512 * 1024 } func (this *ConfigLoader) MramSize() int64 { return 64 * 1024 * 1024 } func (this *ConfigLoader) StackSize() int64 { return 2 * 1024 } func (this *ConfigLoader) HeapSize() int64 { return 4 * 1024 } func (this *ConfigLoader) NumGpRegisters() int { return 24 } func (this *ConfigLoader) MaxNumTasklets() int { return 24 } ================================================ FILE: golang/uPIMulator/src/misc/config_validator.go ================================================ package misc import ( "errors" ) type ConfigValidator struct { config_loader *ConfigLoader } func (this *ConfigValidator) Init(config_loader *ConfigLoader) { this.config_loader = config_loader } func (this *ConfigValidator) Validate() { if this.config_loader.AddressWidth() <= 0 { err := errors.New("address width <= 0") panic(err) } if this.config_loader.AtomicDataWidth() <= 0 { err := errors.New("atomic data width <= 0") panic(err) } if this.config_loader.IramDataWidth() <= 0 { err := errors.New("IRAM data width <= 0") panic(err) } if this.config_loader.WramDataWidth() <= 0 { err := errors.New("WRAM data width <= 0") panic(err) } if this.config_loader.MramDataWidth() <= 0 { err := errors.New("MRAM data width <= 0") panic(err) } if this.config_loader.AtomicOffset() < 0 { err := errors.New("atomic offset < 0") panic(err) } if this.config_loader.IramOffset() < 0 { err := errors.New("IRAM offset < 0") panic(err) } if this.config_loader.WramOffset() < 0 { err := errors.New("WRAM offset < 0") panic(err) } if this.config_loader.MramOffset() < 0 { err := errors.New("MRAM offset < 0") panic(err) } if this.config_loader.AtomicSize() <= 0 { err := errors.New("atomic size <= 0") panic(err) } if this.config_loader.IramSize() <= 0 { err := errors.New("IRAM size <= 0") panic(err) } if this.config_loader.WramSize() <= 0 { err := errors.New("WRAM size <= 0") panic(err) } if this.config_loader.MramSize() <= 0 { err := errors.New("MRAM size <= 0") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.IramOffset(), this.config_loader.IramSize(), ) { err := errors.New("atomic and IRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.WramOffset(), this.config_loader.WramSize(), ) { err := errors.New("atomic and WRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("atomic and MRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.IramOffset(), this.config_loader.IramSize(), this.config_loader.WramOffset(), this.config_loader.WramSize(), ) { err := errors.New("IRAM and WRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.IramOffset(), this.config_loader.IramSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("IRAM and MRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.WramOffset(), this.config_loader.WramSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("WRAM and MRAM are overlapped") panic(err) } if this.config_loader.StackSize() <= 0 { err := errors.New("stack size <= 0") panic(err) } if this.config_loader.HeapSize() <= 0 { err := errors.New("heap size <= 0") panic(err) } if this.config_loader.NumGpRegisters() <= 0 { err := errors.New("num gp registers <= 0") panic(err) } if this.config_loader.MaxNumTasklets() <= 0 { err := errors.New("max num tasklets <= 0") panic(err) } } func (this *ConfigValidator) AreOverlapped( offset1 int64, size1 int64, offset2 int64, size2 int64, ) bool { if offset1 <= offset2 && offset2 <= offset1+size1 { return true } else if offset1 <= offset2+size2 && offset2+size2 <= offset1+size1 { return true } else if offset2 <= offset1 && offset1 <= offset2+size2 { return true } else if offset2 <= offset1+size1 && offset1+size1 <= offset2+size2 { return true } else { return false } } ================================================ FILE: golang/uPIMulator/src/misc/file_dumper.go ================================================ package misc import ( "bufio" "os" ) type FileDumper struct { path string } func (this *FileDumper) Init(path string) { this.path = path } func (this *FileDumper) WriteLines(lines []string) { file, create_err := os.Create(this.path) if create_err != nil { panic(create_err) } defer file.Close() writer := bufio.NewWriter(file) for _, line := range lines { _, write_err := writer.WriteString(line + "\n") if write_err != nil { panic(write_err) } } writer.Flush() } ================================================ FILE: golang/uPIMulator/src/misc/file_scanner.go ================================================ package misc import ( "bufio" "os" ) type FileScanner struct { path string } func (this *FileScanner) Init(path string) { this.path = path } func (this *FileScanner) ReadLines() []string { file, open_err := os.Open(this.path) if open_err != nil { panic(open_err) } defer file.Close() scanner := bufio.NewScanner(file) lines := make([]string, 0) for scanner.Scan() { lines = append(lines, scanner.Text()) } if scan_err := scanner.Err(); scan_err != nil { panic(scan_err) } return lines } ================================================ FILE: golang/uPIMulator/src/misc/stat_factory.go ================================================ package misc import ( "fmt" "slices" ) type StatFactory struct { name string stats map[string]int64 } func (this *StatFactory) Init(name string) { this.name = name this.stats = make(map[string]int64, 0) } func (this *StatFactory) Name() string { return this.name } func (this *StatFactory) Stats() []string { stats := make([]string, 0) for stat, _ := range this.stats { stats = append(stats, stat) } slices.Sort(stats) return stats } func (this *StatFactory) Value(stat string) int64 { return this.stats[stat] } func (this *StatFactory) Increment(stat string, value int64) { this.stats[stat] += value } func (this *StatFactory) ToLines() []string { lines := make([]string, 0) for stat, value := range this.stats { line := fmt.Sprintf("%s_%s: %d", this.name, stat, value) lines = append(lines, line) } return lines } ================================================ FILE: golang/uPIMulator/src/simulator/channel/channel.go ================================================ package channel import ( "errors" "sync" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" "uPIMulator/src/simulator/rank" ) type Channel struct { mutex sync.Mutex channel_id int ranks []*rank.Rank read_bandwidth int64 write_bandwidth int64 input_q *ChannelMessageQ communication_q *ChannelMessageQ ready_q *ChannelMessageQ } func (this *Channel) Init(channel_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } this.channel_id = channel_id this.ranks = make([]*rank.Rank, 0) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) for i := 0; i < num_ranks_per_channel; i++ { rank_ := new(rank.Rank) rank_.Init(channel_id, i, command_line_parser) this.ranks = append(this.ranks, rank_) } this.read_bandwidth = command_line_parser.IntParameter("read_bandwidth") this.write_bandwidth = command_line_parser.IntParameter("write_bandwidth") this.input_q = new(ChannelMessageQ) this.input_q.Init(-1, 0) this.communication_q = new(ChannelMessageQ) this.communication_q.Init(-1, 0) this.ready_q = new(ChannelMessageQ) this.ready_q.Init(-1, 0) } func (this *Channel) Fini() { for _, rank_ := range this.ranks { rank_.Fini() } this.input_q.Fini() this.communication_q.Fini() this.ready_q.Fini() } func (this *Channel) ChannelId() int { return this.channel_id } func (this *Channel) NumRanks() int { return len(this.ranks) } func (this *Channel) Ranks() []*rank.Rank { return this.ranks } func (this *Channel) Dpus() []*dpu.Dpu { dpus := make([]*dpu.Dpu, 0) for _, rank_ := range this.ranks { dpus = append(dpus, rank_.Dpus()...) } return dpus } func (this *Channel) Lock() { this.mutex.Lock() } func (this *Channel) Unlock() { this.mutex.Unlock() } func (this *Channel) CanPush() bool { return this.input_q.CanPush(1) } func (this *Channel) Push(channel_message *ChannelMessage) { if !this.CanPush() { err := errors.New("channel cannot be pushed") panic(err) } this.input_q.Push(channel_message) } func (this *Channel) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Channel) Pop() *ChannelMessage { if !this.CanPop() { err := errors.New("channel cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Channel) CanPopChannelMessage(channel_message *ChannelMessage) bool { for i := 0; this.ready_q.CanPop(i + 1); i++ { cm, _ := this.ready_q.Front(i) if channel_message == cm { return true } } return false } func (this *Channel) PopChannelMessage(channel_message *ChannelMessage) { if !this.CanPopChannelMessage(channel_message) { err := errors.New("channel cannot be popped with the channel message") panic(err) } for i := 0; this.ready_q.CanPop(i + 1); i++ { cm, _ := this.ready_q.Front(i) if channel_message == cm { this.ready_q.Remove(i) } } } func (this *Channel) Cycle() { this.ServiceInputQ() this.ServiceCommunicationQ() this.input_q.Cycle() this.communication_q.Cycle() this.ready_q.Cycle() } func (this *Channel) ServiceInputQ() { if this.input_q.CanPop(1) && this.communication_q.CanPush(1) { channel_messaage := this.input_q.Pop() var latency int64 channel_operation := channel_messaage.ChannelOperation() if channel_operation == READ { latency = channel_messaage.Size() / this.read_bandwidth } else if channel_operation == WRITE { latency = channel_messaage.Size() / this.write_bandwidth } else { err := errors.New("channel operation is not valid") panic(err) } this.communication_q.PushWithTimer(channel_messaage, latency) } } func (this *Channel) ServiceCommunicationQ() { if this.communication_q.CanPop(1) && this.ready_q.CanPush(1) { channel_messaage := this.communication_q.Pop() rank_id := channel_messaage.RankId() rank_ := this.ranks[rank_id] if rank_.RankId() != rank_id { err := errors.New("rank's rank ID != rank ID") panic(err) } dpu_ids := channel_messaage.DpuIds() address := channel_messaage.Address() size := channel_messaage.Size() channel_operation := channel_messaage.ChannelOperation() if channel_operation == READ { byte_streams := make([]*encoding.ByteStream, 0) for _, dpu_id := range dpu_ids { byte_stream := rank_.Read(dpu_id, address, size) byte_streams = append(byte_streams, byte_stream) } channel_messaage.SetByteStreams(byte_streams) } else if channel_operation == WRITE { for i, _ := range dpu_ids { dpu_id := dpu_ids[i] byte_stream := channel_messaage.ByteStreams()[i] rank_.Write(dpu_id, address, byte_stream) } } else { err := errors.New("channel operation is not valid") panic(err) } this.ready_q.Push(channel_messaage) } } ================================================ FILE: golang/uPIMulator/src/simulator/channel/channel_message.go ================================================ package channel import ( "errors" "uPIMulator/src/abi/encoding" ) type ChannelOperation int const ( READ ChannelOperation = iota WRITE ) type ChannelMessage struct { channel_operation ChannelOperation channel_id int rank_id int dpu_ids []int address int64 size int64 byte_streams []*encoding.ByteStream } func (this *ChannelMessage) InitRead( channel_id int, rank_id int, dpu_ids []int, address int64, size int64, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } for _, dpu_id := range dpu_ids { if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } else if dpu_id%8 != dpu_ids[0]%8 { err := errors.New("DPU ID % 8 are different") panic(err) } } this.channel_operation = READ this.channel_id = channel_id this.rank_id = rank_id this.dpu_ids = dpu_ids this.address = address this.size = size this.byte_streams = make([]*encoding.ByteStream, 0) } func (this *ChannelMessage) InitWrite( channel_id int, rank_id int, dpu_ids []int, address int64, size int64, byte_streams []*encoding.ByteStream, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } for _, dpu_id := range dpu_ids { if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } else if dpu_id%8 != dpu_ids[0]%8 { err := errors.New("DPU ID % 8 are different") panic(err) } } for _, byte_stream := range byte_streams { if byte_stream.Size() != size { err := errors.New("byte stream's size != size") panic(err) } } this.channel_operation = WRITE this.channel_id = channel_id this.rank_id = rank_id this.dpu_ids = dpu_ids this.address = address this.size = size this.byte_streams = byte_streams } func (this *ChannelMessage) SetByteStreams(byte_streams []*encoding.ByteStream) { for _, byte_stream := range byte_streams { if byte_stream.Size() != this.size { err := errors.New("byte stream's size != size") panic(err) } } this.byte_streams = byte_streams } func (this *ChannelMessage) ChannelOperation() ChannelOperation { return this.channel_operation } func (this *ChannelMessage) ChannelId() int { return this.channel_id } func (this *ChannelMessage) RankId() int { return this.rank_id } func (this *ChannelMessage) DpuIds() []int { return this.dpu_ids } func (this *ChannelMessage) Address() int64 { return this.address } func (this *ChannelMessage) Size() int64 { return this.size } func (this *ChannelMessage) ByteStreams() []*encoding.ByteStream { return this.byte_streams } ================================================ FILE: golang/uPIMulator/src/simulator/channel/channel_message_q.go ================================================ package channel import ( "errors" ) type ChannelMessageQ struct { size int timer int64 channel_messages []*ChannelMessage cycles []int64 } func (this *ChannelMessageQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.channel_messages = make([]*ChannelMessage, 0) this.cycles = make([]int64, 0) } func (this *ChannelMessageQ) Fini() { if !this.IsEmpty() { err := errors.New("channel message queue is not empty") panic(err) } } func (this *ChannelMessageQ) Size() int { return this.size } func (this *ChannelMessageQ) Timer() int64 { return this.timer } func (this *ChannelMessageQ) IsEmpty() bool { return len(this.channel_messages) == 0 } func (this *ChannelMessageQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.channel_messages) >= num_items } else { return true } } func (this *ChannelMessageQ) Push(channel_message *ChannelMessage) { if !this.CanPush(1) { err := errors.New("channel message queue cannot be pushed") panic(err) } this.channel_messages = append(this.channel_messages, channel_message) this.cycles = append(this.cycles, this.timer) } func (this *ChannelMessageQ) PushWithTimer(channel_message *ChannelMessage, timer int64) { if !this.CanPush(1) { err := errors.New("channel message queue cannot be pushed") panic(err) } this.channel_messages = append(this.channel_messages, channel_message) this.cycles = append(this.cycles, timer) } func (this *ChannelMessageQ) CanPop(num_items int) bool { if len(this.channel_messages) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *ChannelMessageQ) Pop() *ChannelMessage { if !this.CanPop(1) { err := errors.New("channel message queue cannot be popped") panic(err) } channel_message := this.channel_messages[0] this.channel_messages = this.channel_messages[1:] this.cycles = this.cycles[1:] return channel_message } func (this *ChannelMessageQ) Front(pos int) (*ChannelMessage, int64) { if this.IsEmpty() { err := errors.New("channel message queue is empty") panic(err) } return this.channel_messages[pos], this.cycles[pos] } func (this *ChannelMessageQ) Remove(pos int) { this.channel_messages = append(this.channel_messages[:pos], this.channel_messages[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *ChannelMessageQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang/uPIMulator/src/simulator/cycle_job.go ================================================ package simulator import ( "uPIMulator/src/simulator/dpu" ) type CycleJob struct { dpu *dpu.Dpu } func (this *CycleJob) Init(dpu_ *dpu.Dpu) { this.dpu = dpu_ } func (this *CycleJob) Execute() { this.dpu.Cycle() } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dpu.go ================================================ package dpu import ( "errors" "fmt" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu/dram" "uPIMulator/src/simulator/dpu/logic" "uPIMulator/src/simulator/dpu/sram" ) type Dpu struct { channel_id int rank_id int dpu_id int logic_frequency int64 memory_frequency int64 frequency_ratio float64 cycles int64 threads []*logic.Thread thread_scheduler *logic.ThreadScheduler atomic *sram.Atomic iram *sram.Iram wram *sram.Wram mram *dram.Mram operand_collector *logic.OperandCollector memory_controller *dram.MemoryController dma *logic.Dma logic *logic.Logic stat_factory *misc.StatFactory } func (this *Dpu) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.logic_frequency = command_line_parser.IntParameter("logic_frequency") this.memory_frequency = command_line_parser.IntParameter("memory_frequency") this.frequency_ratio = float64(this.memory_frequency) / float64(this.logic_frequency) this.cycles = 0 this.threads = make([]*logic.Thread, 0) num_threads := int(command_line_parser.IntParameter("num_tasklets")) for i := 0; i < num_threads; i++ { thread := new(logic.Thread) thread.Init(i) this.threads = append(this.threads, thread) } this.thread_scheduler = new(logic.ThreadScheduler) this.thread_scheduler.Init(channel_id, rank_id, dpu_id, this.threads, command_line_parser) this.atomic = new(sram.Atomic) this.atomic.Init() this.iram = new(sram.Iram) this.iram.Init() this.wram = new(sram.Wram) this.wram.Init() this.mram = new(dram.Mram) this.mram.Init(command_line_parser) this.operand_collector = new(logic.OperandCollector) this.operand_collector.Init() this.operand_collector.ConnectWram(this.wram) this.memory_controller = new(dram.MemoryController) this.memory_controller.Init(channel_id, rank_id, dpu_id, command_line_parser) this.memory_controller.ConnectMram(this.mram) this.dma = new(logic.Dma) this.dma.Init() this.dma.ConnectAtomic(this.atomic) this.dma.ConnectIram(this.iram) this.dma.ConnectOperandCollector(this.operand_collector) this.dma.ConnectMemoryController(this.memory_controller) this.logic = new(logic.Logic) this.logic.Init(channel_id, rank_id, dpu_id, command_line_parser) this.logic.ConnectThreadScheduler(this.thread_scheduler) this.logic.ConnectAtomic(this.atomic) this.logic.ConnectIram(this.iram) this.logic.ConnectOperandCollector(this.operand_collector) this.logic.ConnectDma(this.dma) name := fmt.Sprintf("DPU%d-%d-%d", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *Dpu) Fini() { for _, thread := range this.threads { thread.Fini() } this.atomic.Fini() this.iram.Fini() this.wram.Fini() this.mram.Fini() this.operand_collector.Fini() this.memory_controller.Fini() this.logic.Fini() this.dma.Fini() } func (this *Dpu) ChannelId() int { return this.channel_id } func (this *Dpu) RankId() int { return this.rank_id } func (this *Dpu) DpuId() int { return this.dpu_id } func (this *Dpu) ThreadScheduler() *logic.ThreadScheduler { return this.thread_scheduler } func (this *Dpu) Logic() *logic.Logic { return this.logic } func (this *Dpu) MemoryController() *dram.MemoryController { return this.memory_controller } func (this *Dpu) Dma() *logic.Dma { return this.dma } func (this *Dpu) Threads() []*logic.Thread { return this.threads } func (this *Dpu) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *Dpu) Boot() { this.thread_scheduler.Boot(0) } func (this *Dpu) IsZombie() bool { for _, thread := range this.threads { if thread.ThreadState() != logic.ZOMBIE { return false } } return this.logic.IsEmpty() && this.memory_controller.IsEmpty() } func (this *Dpu) Cycle() { for _, thread := range this.threads { thread.IncrementIssueCycle() } this.thread_scheduler.Cycle() this.logic.Cycle() this.dma.Cycle() num_memory_cycles := int(this.frequency_ratio*float64(this.cycles) - this.frequency_ratio*float64(this.cycles-1)) for i := 0; i < num_memory_cycles; i++ { this.memory_controller.Cycle() } this.cycles++ } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/dma_command.go ================================================ package dram import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/linker/kernel/instruction" ) type DmaCommand struct { memory_operation MemoryOperation wram_address *int64 mram_address *int64 size int64 byte_stream *encoding.ByteStream acks []bool instruction *instruction.Instruction } func (this *DmaCommand) InitReadFromMram(mram_address int64, size int64) { this.memory_operation = READ this.wram_address = nil this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = nil } func (this *DmaCommand) InitWriteToMram( mram_address int64, size int64, byte_stream *encoding.ByteStream, ) { this.memory_operation = WRITE this.wram_address = nil this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = byte_stream this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = nil } func (this *DmaCommand) InitReadFromMramToWram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if instruction_.OpCode() != instruction.LDMA { err := errors.New("instruction's op code != LDMA") panic(err) } this.memory_operation = READ this.wram_address = new(int64) *this.wram_address = wram_address this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = instruction_ } func (this *DmaCommand) InitWriteToMramFromWram( wram_address int64, mram_address int64, size int64, byte_stream *encoding.ByteStream, instruction_ *instruction.Instruction, ) { if instruction_.OpCode() != instruction.SDMA { err := errors.New("instruction's op code != SDMA") panic(err) } this.memory_operation = WRITE this.wram_address = new(int64) *this.wram_address = wram_address this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = byte_stream this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = instruction_ } func (this *DmaCommand) Fini() { if !this.IsReady() { err := errors.New("DMA command is not ready") panic(err) } } func (this *DmaCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *DmaCommand) WramAddress() int64 { if this.wram_address == nil { err := errors.New("DMA command does not have a WRAM address") panic(err) } return *this.wram_address } func (this *DmaCommand) MramAddress() int64 { if this.mram_address == nil { err := errors.New("DMA command does not have an MRAM address") panic(err) } return *this.mram_address } func (this *DmaCommand) Size() int64 { return this.size } func (this *DmaCommand) HasInstruction() bool { return this.instruction != nil } func (this *DmaCommand) Instruction() *instruction.Instruction { return this.instruction } func (this *DmaCommand) ByteStream(mram_address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(mram_address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } return byte_stream } func (this *DmaCommand) SetByteStream( mram_address int64, size int64, byte_stream *encoding.ByteStream, ) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(mram_address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *DmaCommand) SetAck(mram_address int64, size int64) { for i := int64(0); i < size; i++ { index := this.Index(mram_address) + int(i) if this.acks[index] { err := errors.New("ACK is already set") panic(err) } this.acks[index] = true } } func (this *DmaCommand) IsReady() bool { for _, ack := range this.acks { if !ack { return false } } return true } func (this *DmaCommand) Index(mram_address int64) int { if mram_address < this.MramAddress() { err := errors.New("MRAM address < DMA command's MRAM address") panic(err) } else if mram_address >= this.MramAddress()+this.Size() { err := errors.New("MRAM address >= DMA command's MRAM address + DMA command's size") panic(err) } return int(mram_address - this.MramAddress()) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/dma_command_q.go ================================================ package dram import ( "errors" ) type DmaCommandQ struct { size int timer int64 dma_commands []*DmaCommand cycles []int64 } func (this *DmaCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.dma_commands = make([]*DmaCommand, 0) this.cycles = make([]int64, 0) } func (this *DmaCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("DMA command queue is not empty") panic(err) } } func (this *DmaCommandQ) Size() int { return this.size } func (this *DmaCommandQ) Timer() int64 { return this.timer } func (this *DmaCommandQ) IsEmpty() bool { return len(this.dma_commands) == 0 } func (this *DmaCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.dma_commands) >= num_items } else { return true } } func (this *DmaCommandQ) Push(dma_command *DmaCommand) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, this.timer) } func (this *DmaCommandQ) PushWithTimer(dma_command *DmaCommand, timer int64) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, timer) } func (this *DmaCommandQ) CanPop(num_items int) bool { if len(this.dma_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *DmaCommandQ) Pop() *DmaCommand { if !this.CanPop(1) { err := errors.New("DMA command queue cannot be popped") panic(err) } dma_command := this.dma_commands[0] this.dma_commands = this.dma_commands[1:] this.cycles = this.cycles[1:] return dma_command } func (this *DmaCommandQ) Front(pos int) (*DmaCommand, int64) { if this.IsEmpty() { err := errors.New("DMA command queue is empty") panic(err) } return this.dma_commands[pos], this.cycles[pos] } func (this *DmaCommandQ) Remove(pos int) { this.dma_commands = append(this.dma_commands[:pos], this.dma_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *DmaCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/memory_command.go ================================================ package dram import ( "errors" "uPIMulator/src/abi/encoding" ) type MemoryOperation int const ( ACTIVATION MemoryOperation = iota READ WRITE PRECHARGE ) type MemoryCommand struct { memory_operation MemoryOperation address int64 size int64 byte_stream *encoding.ByteStream dma_command *DmaCommand } func (this *MemoryCommand) InitActivation(memory_operation MemoryOperation, address int64) { this.memory_operation = memory_operation this.address = address this.size = 0 this.byte_stream = nil this.dma_command = nil } func (this *MemoryCommand) InitRead( memory_operation MemoryOperation, address int64, size int64, dma_command *DmaCommand, ) { if memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } else if dma_command.MemoryOperation() != READ { err := errors.New("DMA operation != READ") panic(err) } this.memory_operation = memory_operation this.address = address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.dma_command = dma_command } func (this *MemoryCommand) InitWrite( memory_operation MemoryOperation, address int64, size int64, byte_stream *encoding.ByteStream, dma_command *DmaCommand, ) { if memory_operation != WRITE { err := errors.New("memory operation != WRITE") panic(err) } else if dma_command.MemoryOperation() != WRITE { err := errors.New("DMA operation != WRITE") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } this.memory_operation = memory_operation this.address = address this.size = size this.byte_stream = byte_stream this.dma_command = dma_command } func (this *MemoryCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *MemoryCommand) Address() int64 { return this.address } func (this *MemoryCommand) Size() int64 { return this.size } func (this *MemoryCommand) ByteStream() *encoding.ByteStream { return this.byte_stream } func (this *MemoryCommand) SetByteStream(byte_stream *encoding.ByteStream) { if this.memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } func (this *MemoryCommand) DmaCommand() *DmaCommand { if this.dma_command == nil { err := errors.New("memory command does not have a DMA command") panic(err) } return this.dma_command } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/memory_command_q.go ================================================ package dram import ( "errors" ) type MemoryCommandQ struct { size int timer int64 memory_commands []*MemoryCommand cycles []int64 } func (this *MemoryCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.memory_commands = make([]*MemoryCommand, 0) this.cycles = make([]int64, 0) } func (this *MemoryCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("memory command queue is not empty") panic(err) } } func (this *MemoryCommandQ) Size() int { return this.size } func (this *MemoryCommandQ) Timer() int64 { return this.timer } func (this *MemoryCommandQ) IsEmpty() bool { return len(this.memory_commands) == 0 } func (this *MemoryCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.memory_commands) >= num_items } else { return true } } func (this *MemoryCommandQ) Push(memory_command *MemoryCommand) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, this.timer) } func (this *MemoryCommandQ) PushWithTimer(memory_command *MemoryCommand, timer int64) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, timer) } func (this *MemoryCommandQ) CanPop(num_items int) bool { if len(this.memory_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *MemoryCommandQ) Pop() *MemoryCommand { if !this.CanPop(1) { err := errors.New("memory command queue cannot be popped") panic(err) } memory_command := this.memory_commands[0] this.memory_commands = this.memory_commands[1:] this.cycles = this.cycles[1:] return memory_command } func (this *MemoryCommandQ) Front(pos int) (*MemoryCommand, int64) { if this.IsEmpty() { err := errors.New("memory command queue is empty") panic(err) } return this.memory_commands[pos], this.cycles[pos] } func (this *MemoryCommandQ) Remove(pos int) { this.memory_commands = append(this.memory_commands[:pos], this.memory_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *MemoryCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/memory_controller.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type MemoryController struct { channel_id int rank_id int dpu_id int wordline_size int64 memory_scheduler *MemoryScheduler row_buffer *RowBuffer mram *Mram input_q *DmaCommandQ wait_q *DmaCommandQ memory_command_q *MemoryCommandQ ready_q *DmaCommandQ stat_factory *misc.StatFactory } func (this *MemoryController) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.wordline_size = command_line_parser.IntParameter("wordline_size") this.memory_scheduler = new(MemoryScheduler) this.memory_scheduler.Init(channel_id, rank_id, dpu_id, command_line_parser) this.row_buffer = new(RowBuffer) this.row_buffer.Init(channel_id, rank_id, dpu_id, command_line_parser) this.mram = nil this.input_q = new(DmaCommandQ) this.input_q.Init(-1, 0) this.wait_q = new(DmaCommandQ) this.wait_q.Init(-1, 0) this.memory_command_q = new(MemoryCommandQ) this.memory_command_q.Init(-1, 0) this.ready_q = new(DmaCommandQ) this.ready_q.Init(-1, 0) name := fmt.Sprintf("MemoryController[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *MemoryController) Fini() { this.memory_scheduler.Fini() this.row_buffer.Fini() this.input_q.Fini() this.wait_q.Fini() this.memory_command_q.Fini() this.ready_q.Fini() } func (this *MemoryController) ConnectMram(mram *Mram) { if this.mram != nil { err := errors.New("MRAM is already set") panic(err) } this.mram = mram this.row_buffer.ConnectMram(mram) } func (this *MemoryController) MemoryScheduler() *MemoryScheduler { return this.memory_scheduler } func (this *MemoryController) RowBuffer() *RowBuffer { return this.row_buffer } func (this *MemoryController) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *MemoryController) IsEmpty() bool { return this.memory_scheduler.IsEmpty() && this.row_buffer.IsEmpty() && this.input_q.IsEmpty() && this.wait_q.IsEmpty() && this.memory_command_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *MemoryController) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryController) Push(dma_command *DmaCommand) { if !this.CanPush() { err := errors.New("memory controller cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *MemoryController) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryController) Pop() *DmaCommand { if !this.CanPop() { err := errors.New("memory controller cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryController) Front() *DmaCommand { if !this.CanPop() { err := errors.New("memory controller cannot be popped") panic(err) } dma_command, _ := this.ready_q.Front(0) return dma_command } func (this *MemoryController) Read(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.mram.Read(cur_wordline_address) for i := cur_offset; i < cur_offset+cur_size; i++ { byte_stream.Append(mram_byte_stream.Get(int(i))) } cur_address += cur_size } return byte_stream } func (this *MemoryController) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } cur_byte_stream_offset := int64(0) for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.mram.Read(cur_wordline_address) for i := int64(0); i < cur_size; i++ { mram_byte_stream.Set(int(i+cur_offset), byte_stream.Get(int(i+cur_byte_stream_offset))) } this.mram.Write(cur_wordline_address, mram_byte_stream) cur_address += cur_size cur_byte_stream_offset += cur_size } } func (this *MemoryController) Flush() { this.memory_scheduler.Flush() this.row_buffer.Flush() } func (this *MemoryController) Cycle() { this.ServiceInputQ() this.ServiceScheduler() this.ServiceMemoryCommandQ() this.ServiceRowBuffer() this.ServiceWaitQ() this.memory_scheduler.Cycle() this.row_buffer.Cycle() this.input_q.Cycle() this.wait_q.Cycle() this.memory_command_q.Cycle() this.ready_q.Cycle() this.stat_factory.Increment("memory_cycle", 1) } func (this *MemoryController) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) && this.memory_scheduler.CanPush() { dma_command := this.input_q.Pop() this.memory_scheduler.Push(dma_command) this.wait_q.Push(dma_command) } } func (this *MemoryController) ServiceScheduler() { if this.memory_scheduler.CanPop() && this.memory_command_q.CanPush(1) { memory_command := this.memory_scheduler.Pop() this.memory_command_q.Push(memory_command) } } func (this *MemoryController) ServiceMemoryCommandQ() { if this.memory_command_q.CanPop(1) && this.row_buffer.CanPush() { memory_command := this.memory_command_q.Pop() this.row_buffer.Push(memory_command) } } func (this *MemoryController) ServiceRowBuffer() { if this.row_buffer.CanPop() { memory_command := this.row_buffer.Pop() memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { return } else if memory_operation == PRECHARGE { return } else if memory_operation == READ { address := memory_command.Address() size := memory_command.Size() byte_stream := memory_command.ByteStream() dma_command := memory_command.DmaCommand() dma_command.SetByteStream(address, size, byte_stream) dma_command.SetAck(address, size) } else if memory_operation == WRITE { address := memory_command.Address() size := memory_command.Size() dma_command := memory_command.DmaCommand() dma_command.SetAck(address, size) } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *MemoryController) ServiceWaitQ() { for i := 0; this.wait_q.CanPop(i + 1); i++ { dma_command, _ := this.wait_q.Front(i) if dma_command.IsReady() && this.ready_q.CanPush(1) { this.wait_q.Remove(i) this.ready_q.Push(dma_command) } } } func (this *MemoryController) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *MemoryController) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/memory_scheduler.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/misc" ) type MemoryScheduler struct { channel_id int rank_id int dpu_id int input_q *DmaCommandQ reorder_buffer *MemoryCommandQ ready_q *MemoryCommandQ row_address *int64 wordline_size int64 min_access_granularity int64 stat_factory *misc.StatFactory } func (this *MemoryScheduler) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.input_q = new(DmaCommandQ) this.input_q.Init(-1, 0) this.reorder_buffer = new(MemoryCommandQ) this.reorder_buffer.Init(-1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) this.row_address = nil this.wordline_size = command_line_parser.IntParameter("wordline_size") this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") name := fmt.Sprintf("MemoryScheduler[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *MemoryScheduler) Fini() { this.input_q.Fini() this.reorder_buffer.Fini() this.ready_q.Fini() } func (this *MemoryScheduler) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *MemoryScheduler) IsEmpty() bool { return this.input_q.IsEmpty() && this.reorder_buffer.IsEmpty() && this.ready_q.IsEmpty() } func (this *MemoryScheduler) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryScheduler) Push(dma_command *DmaCommand) { if !this.CanPush() { err := errors.New("memory scheduler cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *MemoryScheduler) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryScheduler) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("memory scheduler cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryScheduler) Flush() { if !this.IsEmpty() { err := errors.New("memory scheduler cannot be flushed") panic(err) } this.row_address = nil } func (this *MemoryScheduler) Cycle() { this.ServiceInputQ() if !this.ReorderFr() { this.ReorderFcFs() } this.input_q.Cycle() this.reorder_buffer.Cycle() this.ready_q.Cycle() } func (this *MemoryScheduler) ServiceInputQ() { if this.input_q.CanPop(1) { dma_command := this.input_q.Pop() this.PopulateMemoryCommands(dma_command) } } func (this *MemoryScheduler) PopulateMemoryCommands(dma_command *DmaCommand) { begin_address := dma_command.MramAddress() end_address := dma_command.MramAddress() + dma_command.Size() for address := begin_address; address < end_address; { wordline_address := this.WordlineAddress(address) size := this.Min( this.Min( address+this.min_access_granularity, wordline_address+this.wordline_size, ), end_address, ) - address memory_operation := dma_command.MemoryOperation() memory_command := new(MemoryCommand) if memory_operation == READ { memory_command.InitRead(READ, address, size, dma_command) } else if memory_operation == WRITE { byte_stream := dma_command.ByteStream(address, size) memory_command.InitWrite(WRITE, address, size, byte_stream, dma_command) } else { err := errors.New("memory operation is not valid") panic(err) } this.reorder_buffer.Push(memory_command) address += size } } func (this *MemoryScheduler) ReorderFr() bool { if this.row_address != nil && this.ready_q.CanPush(1) { for i := 0; this.reorder_buffer.CanPop(i + 1); i++ { memory_command, _ := this.reorder_buffer.Front(i) if this.WordlineAddress(memory_command.Address()) == *this.row_address && this.ready_q.CanPush(1) { if i != 0 { this.stat_factory.Increment("num_fr", 1) } else { this.stat_factory.Increment("num_fcfs", 1) } this.reorder_buffer.Remove(i) this.ready_q.Push(memory_command) return true } } } return false } func (this *MemoryScheduler) ReorderFcFs() bool { if this.reorder_buffer.CanPop(1) && this.row_address != nil && this.ready_q.CanPush(3) { memory_command := this.reorder_buffer.Pop() wordline_address := this.WordlineAddress(memory_command.Address()) if wordline_address == *this.row_address { err := errors.New("FR has not worked correctly") panic(err) } precharge := new(MemoryCommand) precharge.InitActivation(PRECHARGE, *this.row_address) activation := new(MemoryCommand) activation.InitActivation(ACTIVATION, wordline_address) this.ready_q.Push(precharge) this.ready_q.Push(activation) this.ready_q.Push(memory_command) *this.row_address = wordline_address return true } else if this.reorder_buffer.CanPop(1) && this.row_address == nil && this.ready_q.CanPush(2) { memory_command := this.reorder_buffer.Pop() wordline_address := this.WordlineAddress(memory_command.Address()) activation := new(MemoryCommand) activation.InitActivation(ACTIVATION, wordline_address) this.ready_q.Push(activation) this.ready_q.Push(memory_command) this.row_address = new(int64) *this.row_address = wordline_address return true } else { return false } } func (this *MemoryScheduler) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *MemoryScheduler) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/mram.go ================================================ package dram import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type Mram struct { address int64 size int64 wordline_size int64 wordlines []*Wordline } func (this *Mram) Init(command_line_parser *misc.CommandLineParser) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.MramOffset() this.size = config_loader.MramSize() this.wordline_size = command_line_parser.IntParameter("wordline_size") if this.wordline_size <= 0 { err := errors.New("wordline size <= 0") panic(err) } else if this.address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if this.size%this.wordline_size != 0 { err := errors.New("size is not aligned with wordline size") panic(err) } this.wordlines = make([]*Wordline, 0) num_wordlines := int(this.size / this.wordline_size) for i := 0; i < num_wordlines; i++ { wordline := new(Wordline) wordline.Init(this.address+int64(i)*this.wordline_size, this.wordline_size) this.wordlines = append(this.wordlines, wordline) } } func (this *Mram) Fini() { for _, wordline := range this.wordlines { wordline.Fini() } } func (this *Mram) Address() int64 { return this.address } func (this *Mram) Size() int64 { return this.size } func (this *Mram) Read(address int64) *encoding.ByteStream { return this.wordlines[this.Index(address)].Read() } func (this *Mram) Write(address int64, byte_stream *encoding.ByteStream) { this.wordlines[this.Index(address)].Write(byte_stream) } func (this *Mram) Index(address int64) int { if address < this.address { err := errors.New("address < MRAM offset") panic(err) } else if address+this.wordline_size > this.address+this.size { err := errors.New("address + wordline size > MRAM offset + MRAM size") panic(err) } else if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } return int((address - this.address) / this.wordline_size) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/row_buffer.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type RowBuffer struct { channel_id int rank_id int dpu_id int t_ras int64 t_rcd int64 t_cl int64 t_bl int64 t_rp int64 wordline_size int64 mram *Mram row_address *int64 row_buffer *encoding.ByteStream input_q *MemoryCommandQ ready_q *MemoryCommandQ activation_q *MemoryCommandQ io_q *MemoryCommandQ bus_q *MemoryCommandQ precharge_q *MemoryCommandQ stat_factory *misc.StatFactory } func (this *RowBuffer) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.t_ras = command_line_parser.IntParameter("t_ras") this.t_rcd = command_line_parser.IntParameter("t_rcd") this.t_cl = command_line_parser.IntParameter("t_cl") this.t_bl = command_line_parser.IntParameter("t_bl") this.t_rp = command_line_parser.IntParameter("t_rp") this.wordline_size = command_line_parser.IntParameter("wordline_size") this.mram = nil this.row_address = nil this.row_buffer = nil this.input_q = new(MemoryCommandQ) this.input_q.Init(1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) this.activation_q = new(MemoryCommandQ) this.activation_q.Init(1, this.t_ras) this.io_q = new(MemoryCommandQ) this.io_q.Init(1, this.t_cl) this.bus_q = new(MemoryCommandQ) this.bus_q.Init(1, this.t_bl) this.precharge_q = new(MemoryCommandQ) this.precharge_q.Init(1, this.t_rp) name := fmt.Sprintf("RowBuffer[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *RowBuffer) Fini() { this.input_q.Fini() this.ready_q.Fini() this.activation_q.Fini() this.io_q.Fini() this.bus_q.Fini() this.precharge_q.Fini() } func (this *RowBuffer) ConnectMram(mram *Mram) { if this.mram != nil { err := errors.New("MRAM is already connected") panic(err) } this.mram = mram } func (this *RowBuffer) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *RowBuffer) IsEmpty() bool { return this.input_q.IsEmpty() && this.ready_q.IsEmpty() && this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() } func (this *RowBuffer) CanPush() bool { return this.input_q.CanPush(1) } func (this *RowBuffer) Push(memory_command *MemoryCommand) { if !this.CanPush() { err := errors.New("row buffer cannot be pushed") panic(err) } this.input_q.Push(memory_command) } func (this *RowBuffer) CanPop() bool { return this.ready_q.CanPop(1) } func (this *RowBuffer) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("row buffer cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *RowBuffer) Flush() { if this.row_address != nil { this.WriteToMram() this.row_address = nil this.row_buffer = nil } } func (this *RowBuffer) Cycle() { this.ServiceInputQ() this.ServiceActivationQ() this.ServiceIoQ() this.ServiceBusQ() this.ServicePrechargeQ() this.input_q.Cycle() this.ready_q.Cycle() this.activation_q.Cycle() this.io_q.Cycle() this.bus_q.Cycle() this.precharge_q.Cycle() } func (this *RowBuffer) ServiceInputQ() { if this.input_q.CanPop(1) { memory_command, _ := this.input_q.Front(0) memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { if this.activation_q.IsEmpty() && this.row_address == nil { this.activation_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == READ { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == WRITE { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == PRECHARGE { if this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() { this.precharge_q.Push(memory_command) this.input_q.Pop() } } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServiceActivationQ() { if !this.activation_q.IsEmpty() { memory_command, cycle := this.activation_q.Front(0) if cycle == this.t_ras-this.t_rcd { if this.row_address != nil { err := errors.New("row buffer is not precharged") panic(err) } else if memory_command.Address()%this.wordline_size != 0 { err := errors.New("memory command is not aligned with wordline size") panic(err) } this.row_address = new(int64) *this.row_address = memory_command.Address() this.row_buffer = this.ReadFromMram() } } if this.activation_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.activation_q.Pop() this.ready_q.Push(memory_command) this.stat_factory.Increment("num_activations", 1) } } func (this *RowBuffer) ServiceIoQ() { if this.io_q.CanPop(1) && this.bus_q.CanPush(1) { memory_command := this.io_q.Pop() this.bus_q.Push(memory_command) } } func (this *RowBuffer) ServiceBusQ() { if this.bus_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.bus_q.Pop() this.ready_q.Push(memory_command) memory_operation := memory_command.MemoryOperation() if memory_operation == READ { byte_stream := this.ReadFromRowBuffer(memory_command.Address(), memory_command.Size()) memory_command.SetByteStream(byte_stream) this.stat_factory.Increment("num_reads", 1) this.stat_factory.Increment("read_bytes", memory_command.Size()) } else if memory_operation == WRITE { this.WriteToRowBuffer(memory_command.Address(), memory_command.Size(), memory_command.ByteStream()) this.stat_factory.Increment("num_writes", 1) this.stat_factory.Increment("write_bytes", memory_command.Size()) } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServicePrechargeQ() { if this.precharge_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.precharge_q.Pop() address := memory_command.Address() if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if address != *this.row_address { err := errors.New("address != row address") panic(err) } this.WriteToMram() this.row_address = nil this.ready_q.Push(memory_command) this.stat_factory.Increment("num_precharges", 1) } } func (this *RowBuffer) ReadFromMram() *encoding.ByteStream { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } return this.mram.Read(*this.row_address) } func (this *RowBuffer) ReadFromRowBuffer(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.row_buffer.Get(index)) } return byte_stream } func (this *RowBuffer) WriteToMram() { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } this.mram.Write(*this.row_address, this.row_buffer) } func (this *RowBuffer) WriteToRowBuffer( address int64, size int64, byte_stream *encoding.ByteStream, ) { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(address) + int(i) this.row_buffer.Set(index, byte_stream.Get(int(i))) } } func (this *RowBuffer) Index(address int64) int { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if address < *this.row_address { err := errors.New("address < row address") panic(err) } else if address >= *this.row_address+this.wordline_size { err := errors.New("address >= row address + wordline size") panic(err) } return int(address - *this.row_address) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/dram/wordline.go ================================================ package dram import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type Wordline struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Wordline) Init(address int64, size int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_size := int64(config_loader.MramDataWidth() / 8) if address < 0 { err := errors.New("address < 0") panic(err) } else if size <= 0 { err := errors.New("size <= 0") panic(err) } else if size%mram_data_size != 0 { err := errors.New("size is not aligned with MRAM data size") panic(err) } this.address = address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } } func (this *Wordline) Fini() { } func (this *Wordline) Read() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < this.byte_stream.Size(); i++ { byte_stream.Append(this.byte_stream.Get(int(i))) } return byte_stream } func (this *Wordline) Write(byte_stream *encoding.ByteStream) { if this.size != byte_stream.Size() { err := errors.New("wordline's size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/alu.go ================================================ package logic import ( "errors" "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type Alu struct { } func (this *Alu) Init() { } func (this *Alu) Fini() { } func (this *Alu) AtomicAddressHash(operand1 int64, operand2 int64) int64 { if operand1+operand2 >= 256 { err := errors.New("operand1 + operand2 >= 256") panic(err) } result, _, _ := this.Add(operand1, operand2) return result } func (this *Alu) Add(operand1 int64, operand2 int64) (int64, bool, bool) { return this.Addc(operand1, operand2, false) } func (this *Alu) Addc(operand1 int64, operand2 int64, carry_flag bool) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 if carry_flag { result = word1.Value(word.UNSIGNED) + word2.Value(word.UNSIGNED) + 1 } else { result = word1.Value(word.UNSIGNED) + word2.Value(word.UNSIGNED) } max_unsigned_value := this.Pow2(mram_data_width) - 1 var carry bool if result > max_unsigned_value { result %= this.Pow2(mram_data_width) carry = true } else { carry = false } result_word := new(word.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else if !word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else { overflow = false } return result, carry, overflow } func (this *Alu) Sub(operand1 int64, operand2 int64) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 var carry bool if word1.Value(word.UNSIGNED) >= word2.Value(word.UNSIGNED) { result = word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) carry = true } result_word := new(word.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else if !word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else { overflow = false } return result, carry, overflow } func (this *Alu) Subc(operand1 int64, operand2 int64, carry_flag bool) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 var carry bool if carry_flag { if word1.Value(word.UNSIGNED)+1 >= word2.Value(word.UNSIGNED) { result = word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) - 1 carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) - 1 carry = true } } else { if word1.Value(word.UNSIGNED) >= word2.Value(word.UNSIGNED) { result = word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(word.UNSIGNED) - word2.Value(word.UNSIGNED) carry = true } } result_word := new(word.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else if !word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else { overflow = false } return result, carry, overflow } func (this *Alu) And(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Nand(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Andn(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Or(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) || word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Nor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) || word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Orn(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) || word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Xor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else if word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Nxor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else if word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Asr(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) msb := word_.SignBit() shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { if msb { result_word.SetBit(i) } else { result_word.ClearBit(i) } } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Lsl(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { result_word.ClearBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) LslAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Lsl(operand2, shift)) } func (this *Alu) LslSub(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Sub(operand1, this.Lsl(operand2, shift)) } func (this *Alu) Lsl1(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { result_word.SetBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Lsl1x(operand int64, shift int64) int64 { err := errors.New("lsl1x is not yet implemented") panic(err) } func (this *Alu) Lslx(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) if shift_value == 0 { return 0 } else { return this.Lsr(operand, int64(mram_data_width)-shift_value) } } func (this *Alu) Lsr(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { result_word.ClearBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) LsrAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Lsr(operand2, shift)) } func (this *Alu) Lsr1(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { result_word.SetBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Lsr1x(operand int64, shift int64) int64 { err := errors.New("lsr1x is not yet implemented") panic(err) } func (this *Alu) Lsrx(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) if shift_value == 0 { return 0 } else { return this.Lsl(operand, int64(mram_data_width)-shift_value) } } func (this *Alu) Rol(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { if word_.Bit(i + mram_data_width - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } result_word.SetBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) RolAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Rol(operand2, shift)) } func (this *Alu) Ror(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(word.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(word.UNSIGNED, 0, 5) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { if word_.Bit((i + int(shift_value)) % mram_data_width) { result_word.SetBit(i) } else { result_word.ClearBit(i) } result_word.SetBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Cao(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) ones := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(i) { ones++ } } return ones } func (this *Alu) Clo(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) leading_ones := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(mram_data_width - 1 - i) { leading_ones++ } else { break } } return leading_ones } func (this *Alu) Cls(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) msb := word_.SignBit() leading_sign_bits := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(mram_data_width-1-i) == msb { leading_sign_bits++ } else { break } } return leading_sign_bits } func (this *Alu) Clz(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) leading_zeros := int64(0) for i := 0; i < mram_data_width; i++ { if !word_.Bit(mram_data_width - 1 - i) { leading_zeros++ } else { break } } return leading_zeros } func (this *Alu) Cmpb4(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) for i := 0; i < 4; i++ { begin := 8 * i end := 8 * (i + 1) byte1 := word1.BitSlice(word.UNSIGNED, begin, end) byte2 := word2.BitSlice(word.UNSIGNED, begin, end) if byte1 == byte2 { result_word.SetBitSlice(begin, end, 1) } else { result_word.SetBitSlice(begin, end, 0) } } return result_word.Value(word.UNSIGNED) } func (this *Alu) Extsb(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(word.SIGNED, 0, 8) } func (this *Alu) Extsh(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(word.SIGNED, 0, 16) } func (this *Alu) Extub(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(word.UNSIGNED, 0, 8) } func (this *Alu) Extuh(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(word.UNSIGNED, 0, 16) } func (this *Alu) MulShSh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 8, 16) * word2.BitSlice(word.SIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulShSl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 8, 16) * word2.BitSlice(word.SIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulShUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 8, 16) * word2.BitSlice(word.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulShUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 8, 16) * word2.BitSlice(word.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulSlSh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 0, 8) * word2.BitSlice(word.SIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulSlSl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 0, 8) * word2.BitSlice(word.SIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulSlUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 0, 8) * word2.BitSlice(word.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulSlUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.SIGNED, 0, 8) * word2.BitSlice(word.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.SIGNED) } func (this *Alu) MulUhUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.UNSIGNED, 8, 16) * word2.BitSlice(word.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.UNSIGNED) } func (this *Alu) MulUhUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.UNSIGNED, 8, 16) * word2.BitSlice(word.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.UNSIGNED) } func (this *Alu) MulUlUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.UNSIGNED, 0, 8) * word2.BitSlice(word.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(word.UNSIGNED) } func (this *Alu) MulUlUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(word.Word) result_word.Init(mram_data_width) result := word1.BitSlice(word.UNSIGNED, 0, 8) * word2.BitSlice(word.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(word.UNSIGNED) } func (this *Alu) Sats(operand int64) int64 { err := errors.New("sats is not yet implemented") panic(err) } func (this *Alu) Hash(operand1 int64, operand2 int64) int64 { err := errors.New("hash is not yet implemented") panic(err) } func (this *Alu) SignedExtension(operand int64) (int64, int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) even_word := new(word.Word) even_word.Init(mram_data_width) if word_.SignBit() { even_word.SetValue(-1) } odd_word := new(word.Word) odd_word.Init(mram_data_width) odd_word.SetValue(word_.Value(word.UNSIGNED)) return even_word.Value(word.UNSIGNED), odd_word.Value(word.UNSIGNED) } func (this *Alu) UnsignedExtension(operand int64) (int64, int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(word.Word) word_.Init(mram_data_width) word_.SetValue(operand) even_word := new(word.Word) even_word.Init(mram_data_width) even_word.SetValue(0) odd_word := new(word.Word) odd_word.Init(mram_data_width) odd_word.SetValue(word_.Value(word.UNSIGNED)) return even_word.Value(word.UNSIGNED), odd_word.Value(word.UNSIGNED) } func (this *Alu) Pow2(exponent int) int64 { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/cycle_rule.go ================================================ package logic import ( "errors" "fmt" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/misc" ) type CycleRule struct { channel_id int rank_id int dpu_id int input_q *InstructionQ wait_q *InstructionQ ready_q *InstructionQ scoreboard map[*instruction.Instruction]*Thread reg_sets []*RegSet stat_factory *misc.StatFactory } func (this *CycleRule) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id num_tasklets := int(command_line_parser.IntParameter("num_tasklets")) this.input_q = new(InstructionQ) this.input_q.Init(1, 0) this.wait_q = new(InstructionQ) this.wait_q.Init(1, 0) this.ready_q = new(InstructionQ) this.ready_q.Init(1, 0) this.scoreboard = make(map[*instruction.Instruction]*Thread, 0) for i := 0; i < num_tasklets; i++ { reg_set := new(RegSet) reg_set.Init(i) this.reg_sets = append(this.reg_sets, reg_set) } name := fmt.Sprintf("CycleRule[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *CycleRule) Fini() { this.input_q.Fini() this.wait_q.Fini() this.ready_q.Fini() } func (this *CycleRule) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *CycleRule) IsEmpty() bool { return this.input_q.IsEmpty() && this.wait_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *CycleRule) CanPush() bool { return this.input_q.CanPush(1) } func (this *CycleRule) Push(instruction_ *instruction.Instruction, thread *Thread) { if !this.CanPush() { err := errors.New("cycle rule cannot be pushed") panic(err) } this.input_q.Push(instruction_) this.scoreboard[instruction_] = thread } func (this *CycleRule) CanPop() bool { return this.ready_q.CanPop(1) } func (this *CycleRule) Pop() *instruction.Instruction { if !this.CanPop() { err := errors.New("cycle rule cannot be popped") panic(err) } instruction_ := this.ready_q.Pop() delete(this.scoreboard, instruction_) return instruction_ } func (this *CycleRule) Cycle() { this.ServiceInputQ() this.ServiceWaitQ() this.input_q.Cycle() this.wait_q.Cycle() this.ready_q.Cycle() } func (this *CycleRule) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) { instruction_ := this.input_q.Pop() thread_id := this.scoreboard[instruction_].ThreadId() this.reg_sets[thread_id].CollectReadGpRegs(instruction_) extra_cycles := this.CalculateExtraCycles(instruction_) this.wait_q.PushWithTimer(instruction_, extra_cycles) this.stat_factory.Increment("cycle_rule", extra_cycles) } } func (this *CycleRule) ServiceWaitQ() { if this.wait_q.CanPop(1) && this.ready_q.CanPush(1) { instruction_ := this.wait_q.Pop() this.ready_q.Push(instruction_) thread_id := this.scoreboard[instruction_].ThreadId() this.reg_sets[thread_id].Clear() this.reg_sets[thread_id].CollectWriteGpRegs(instruction_) } } func (this *CycleRule) CalculateExtraCycles(instruction_ *instruction.Instruction) int64 { thread_id := this.scoreboard[instruction_].ThreadId() reg_set := this.reg_sets[thread_id] if reg_set.ThreadId() != thread_id { err := errors.New("reg set's thread ID != thread ID") panic(err) } reg_indicies := reg_set.RegIndices() even_counter := 0 odd_counter := 0 for reg_index, _ := range reg_indicies { if reg_index%2 == 0 { even_counter++ } else { odd_counter++ } } return int64(even_counter/2 + odd_counter/2) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/dma.go ================================================ package logic import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu/dram" "uPIMulator/src/simulator/dpu/sram" ) type Dma struct { atomic *sram.Atomic iram *sram.Iram operand_collector *OperandCollector memory_controller *dram.MemoryController input_q *dram.DmaCommandQ ready_q *dram.DmaCommandQ } func (this *Dma) Init() { this.atomic = nil this.iram = nil this.operand_collector = nil this.memory_controller = nil config_loader := new(misc.ConfigLoader) config_loader.Init() max_num_tasklets := config_loader.MaxNumTasklets() this.input_q = new(dram.DmaCommandQ) this.input_q.Init(max_num_tasklets, 0) this.ready_q = new(dram.DmaCommandQ) this.ready_q.Init(max_num_tasklets, 0) } func (this *Dma) Fini() { this.input_q.Fini() this.ready_q.Fini() } func (this *Dma) ConnectAtomic(atomic *sram.Atomic) { if this.atomic != nil { err := errors.New("atomic is already set") panic(err) } this.atomic = atomic } func (this *Dma) ConnectIram(iram *sram.Iram) { if this.iram != nil { err := errors.New("IRAM is already set") panic(err) } this.iram = iram } func (this *Dma) ConnectOperandCollector(operand_collector *OperandCollector) { if this.operand_collector != nil { err := errors.New("operand collector is already set") panic(err) } this.operand_collector = operand_collector } func (this *Dma) ConnectMemoryController(memory_controller *dram.MemoryController) { if this.memory_controller != nil { err := errors.New("memory controller is already set") panic(err) } this.memory_controller = memory_controller } func (this *Dma) IsEmpty() bool { return this.input_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *Dma) TransferToAtomic(address int64, byte_stream *encoding.ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { if byte_stream.Get(int(i)) != 0 { err := errors.New("atomic byte is not set to 0") panic(err) } } } func (this *Dma) TransferToIram(address int64, byte_stream *encoding.ByteStream) { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_offset := config_loader.IramOffset() iram_data_size := int64(config_loader.IramDataWidth() / 8) if address != this.iram.Address() { err := errors.New("address != IRAM's address") panic(err) } else if byte_stream.Size()%iram_data_size != 0 { err := errors.New("byte stream's size is not aligned with IRAM data size") panic(err) } this.iram.Write(iram_offset, byte_stream) } func (this *Dma) TransferFromWram(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { value := this.operand_collector.Lbu(address + i) byte_stream.Append(uint8(value)) } return byte_stream } func (this *Dma) TransferToWram(address int64, byte_stream *encoding.ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) this.operand_collector.Sb(address+i, int64(value)) } } func (this *Dma) TransferFromMram(address int64, size int64) *encoding.ByteStream { this.memory_controller.Flush() return this.memory_controller.Read(address, size) } func (this *Dma) TransferToMram(address int64, byte_stream *encoding.ByteStream) { this.memory_controller.Write(address, byte_stream.Size(), byte_stream) } func (this *Dma) TransferFromWramToMram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } byte_stream := this.TransferFromWram(wram_address, size) dma_command := new(dram.DmaCommand) dma_command.InitWriteToMramFromWram(wram_address, mram_address, size, byte_stream, instruction_) this.Push(dma_command) } func (this *Dma) TransferFromMramToWram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } dma_command := new(dram.DmaCommand) dma_command.InitReadFromMramToWram(wram_address, mram_address, size, instruction_) this.Push(dma_command) } func (this *Dma) CanPush() bool { return this.input_q.CanPush(1) } func (this *Dma) Push(dma_command *dram.DmaCommand) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *Dma) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Dma) Pop() *dram.DmaCommand { if !this.CanPop() { err := errors.New("DMA cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Dma) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() } func (this *Dma) ServiceInputQ() { if this.input_q.CanPop(1) && this.memory_controller.CanPush() { dma_command := this.input_q.Pop() this.memory_controller.Push(dma_command) } } func (this *Dma) ServiceReadyQ() { if this.memory_controller.CanPop() && this.ready_q.CanPush(1) { dma_command := this.memory_controller.Pop() this.ready_q.Push(dma_command) if dma_command.MemoryOperation() == dram.READ { wram_address := dma_command.WramAddress() mram_address := dma_command.MramAddress() size := dma_command.Size() byte_stream := dma_command.ByteStream(mram_address, size) this.TransferToWram(wram_address, byte_stream) } } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/instruction_q.go ================================================ package logic import ( "errors" "uPIMulator/src/linker/kernel/instruction" ) type InstructionQ struct { size int timer int64 instructions []*instruction.Instruction cycles []int64 } func (this *InstructionQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.instructions = make([]*instruction.Instruction, 0) this.cycles = make([]int64, 0) } func (this *InstructionQ) Fini() { if !this.IsEmpty() { err := errors.New("instruction queue is not empty") panic(err) } } func (this *InstructionQ) Size() int { return this.size } func (this *InstructionQ) Timer() int64 { return this.timer } func (this *InstructionQ) IsEmpty() bool { return len(this.instructions) == 0 } func (this *InstructionQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.instructions) >= num_items } else { return true } } func (this *InstructionQ) Push(instruction_ *instruction.Instruction) { if !this.CanPush(1) { err := errors.New("instruction queue cannot be pushed") panic(err) } this.instructions = append(this.instructions, instruction_) this.cycles = append(this.cycles, this.timer) } func (this *InstructionQ) PushWithTimer(instruction_ *instruction.Instruction, timer int64) { if !this.CanPush(1) { err := errors.New("instruction queue cannot be pushed") panic(err) } this.instructions = append(this.instructions, instruction_) this.cycles = append(this.cycles, timer) } func (this *InstructionQ) CanPop(num_items int) bool { if len(this.instructions) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *InstructionQ) Pop() *instruction.Instruction { if !this.CanPop(1) { err := errors.New("instruction queue cannot be popped") panic(err) } instruction_ := this.instructions[0] this.instructions = this.instructions[1:] this.cycles = this.cycles[1:] return instruction_ } func (this *InstructionQ) Front(pos int) (*instruction.Instruction, int64) { if this.IsEmpty() { err := errors.New("instruction queue is empty") panic(err) } return this.instructions[pos], this.cycles[pos] } func (this *InstructionQ) Remove(pos int) { this.instructions = append(this.instructions[:pos], this.instructions[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *InstructionQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/logic.go ================================================ package logic import ( "errors" "fmt" "math" "uPIMulator/src/abi/word" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/linker/kernel/instruction/cc" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu/sram" ) type Logic struct { channel_id int rank_id int dpu_id int num_channels int num_ranks_per_channel int num_dpus_per_rank int verbose int min_access_granularity int64 thread_scheduler *ThreadScheduler atomic *sram.Atomic iram *sram.Iram operand_collector *OperandCollector dma *Dma scoreboard map[*instruction.Instruction]*Thread pipeline *Pipeline cycle_rule *CycleRule alu *Alu wait_q *InstructionQ stat_factory *misc.StatFactory } func (this *Logic) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.num_channels = int(command_line_parser.IntParameter("num_channels")) this.num_ranks_per_channel = int(command_line_parser.IntParameter("num_ranks_per_channel")) this.num_dpus_per_rank = int(command_line_parser.IntParameter("num_dpus_per_rank")) this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.verbose = int(command_line_parser.IntParameter("verbose")) this.thread_scheduler = nil this.atomic = nil this.iram = nil this.operand_collector = nil this.dma = nil this.scoreboard = make(map[*instruction.Instruction]*Thread, 0) this.pipeline = new(Pipeline) this.pipeline.Init(command_line_parser) this.cycle_rule = new(CycleRule) this.cycle_rule.Init(channel_id, rank_id, dpu_id, command_line_parser) this.alu = new(Alu) this.alu.Init() config_loader := new(misc.ConfigLoader) config_loader.Init() this.wait_q = new(InstructionQ) this.wait_q.Init(config_loader.MaxNumTasklets(), 0) name := fmt.Sprintf("Logic[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *Logic) Fini() { this.pipeline.Fini() this.cycle_rule.Fini() this.alu.Fini() this.wait_q.Fini() } func (this *Logic) ConnectThreadScheduler(thread_scheduler *ThreadScheduler) { if this.thread_scheduler != nil { err := errors.New("thread scheduler is already set") panic(err) } this.thread_scheduler = thread_scheduler } func (this *Logic) ConnectAtomic(atomic *sram.Atomic) { if this.atomic != nil { err := errors.New("atomic is already set") panic(err) } this.atomic = atomic } func (this *Logic) ConnectIram(iram *sram.Iram) { if this.iram != nil { err := errors.New("IRAM is already set") panic(err) } this.iram = iram } func (this *Logic) ConnectOperandCollector(operand_collector *OperandCollector) { if this.operand_collector != nil { err := errors.New("operand collector is already set") panic(err) } this.operand_collector = operand_collector } func (this *Logic) ConnectDma(dma *Dma) { if this.dma != nil { err := errors.New("DMA is already set") panic(err) } this.dma = dma } func (this *Logic) CycleRule() *CycleRule { return this.cycle_rule } func (this *Logic) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *Logic) IsEmpty() bool { return this.pipeline.IsEmpty() && this.cycle_rule.IsEmpty() && this.wait_q.IsEmpty() } func (this *Logic) Cycle() { this.ServiceThreadScheduler() this.ServicePipeline() this.ServiceCycleRule() this.ServiceLogic() this.ServiceDma() this.pipeline.Cycle() this.cycle_rule.Cycle() this.wait_q.Cycle() this.stat_factory.Increment("logic_cycle", 1) } func (this *Logic) ServiceThreadScheduler() { if this.pipeline.CanPush() && this.cycle_rule.CanPush() && this.wait_q.CanPush(1) { thread := this.thread_scheduler.Schedule() if thread != nil { pc := thread.RegFile().ReadPcReg() instruction_ := this.iram.Read(pc) this.scoreboard[instruction_] = thread this.pipeline.Push(instruction_) if instruction_.Suffix() != instruction.DMA_RRI { this.ExecuteInstruction(instruction_) } else { this.thread_scheduler.Block(thread.ThreadId()) thread.RegFile().IncrementPcReg() this.wait_q.Push(instruction_) } this.stat_factory.Increment("num_instructions", 1) } active_tasklets := fmt.Sprintf("active_tasklets_%d", this.thread_scheduler.NumIssuableThreads()) this.stat_factory.Increment(active_tasklets, 1) } else { this.stat_factory.Increment("backpressure", 1) this.stat_factory.Increment("active_tasklets_0", 1) } } func (this *Logic) ServicePipeline() { if this.pipeline.CanPop() && this.cycle_rule.CanPush() { instruction_ := this.pipeline.Pop() thread := this.scoreboard[instruction_] if instruction_ != nil { this.cycle_rule.Push(instruction_, thread) } } } func (this *Logic) ServiceCycleRule() { if this.cycle_rule.CanPop() { instruction_ := this.cycle_rule.Pop() if instruction_.Suffix() != instruction.DMA_RRI { delete(this.scoreboard, instruction_) } else { this.ExecuteInstruction(instruction_) } } } func (this *Logic) ServiceLogic() { } func (this *Logic) ServiceDma() { if this.dma.CanPop() { dma_command := this.dma.Pop() has_waked_up := false for i := 0; this.wait_q.CanPop(i + 1); i++ { instruction_, _ := this.wait_q.Front(i) if dma_command.Instruction() == instruction_ { thread := this.scoreboard[instruction_] this.thread_scheduler.Awake(thread.ThreadId()) this.wait_q.Remove(i) delete(this.scoreboard, instruction_) has_waked_up = true break } } if !has_waked_up { err := errors.New("DMA command has not waked up an instruction") panic(err) } } } func (this *Logic) ExecuteInstruction(instruction_ *instruction.Instruction) { thread := this.scoreboard[instruction_] unique_dpu_id := this.channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + this.rank_id*this.num_dpus_per_rank + this.dpu_id if this.verbose >= 1 { fmt.Printf( "{%d}[%d] %s\n", unique_dpu_id, thread.ThreadId(), instruction_.Stringify(), ) } suffix := instruction_.Suffix() if suffix == instruction.RICI { this.ExecuteRici(instruction_) } else if suffix == instruction.RRI { this.ExecuteRri(instruction_) } else if suffix == instruction.RRIC { this.ExecuteRric(instruction_) } else if suffix == instruction.RRICI { this.ExecuteRrici(instruction_) } else if suffix == instruction.RRIF { this.ExecuteRrif(instruction_) } else if suffix == instruction.RRR { this.ExecuteRrr(instruction_) } else if suffix == instruction.RRRC { this.ExecuteRrrc(instruction_) } else if suffix == instruction.RRRCI { this.ExecuteRrrci(instruction_) } else if suffix == instruction.ZRI { this.ExecuteZri(instruction_) } else if suffix == instruction.ZRIC { this.ExecuteZric(instruction_) } else if suffix == instruction.ZRICI { this.ExecuteZrici(instruction_) } else if suffix == instruction.ZRIF { this.ExecuteZrif(instruction_) } else if suffix == instruction.ZRR { this.ExecuteZrr(instruction_) } else if suffix == instruction.ZRRC { this.ExecuteZrrc(instruction_) } else if suffix == instruction.ZRRCI { this.ExecuteZrrci(instruction_) } else if suffix == instruction.S_RRI || suffix == instruction.U_RRI { this.ExecuteSRri(instruction_) } else if suffix == instruction.S_RRIC || suffix == instruction.U_RRIC { this.ExecuteSRric(instruction_) } else if suffix == instruction.S_RRICI || suffix == instruction.U_RRICI { this.ExecuteSRrici(instruction_) } else if suffix == instruction.S_RRIF || suffix == instruction.U_RRIF { this.ExecuteSRrif(instruction_) } else if suffix == instruction.S_RRR || suffix == instruction.U_RRR { this.ExecuteSRrr(instruction_) } else if suffix == instruction.S_RRRC || suffix == instruction.U_RRRC { this.ExecuteSRrrc(instruction_) } else if suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI { this.ExecuteSRrrci(instruction_) } else if suffix == instruction.RR { this.ExecuteRr(instruction_) } else if suffix == instruction.RRC { this.ExecuteRrc(instruction_) } else if suffix == instruction.RRCI { this.ExecuteRrci(instruction_) } else if suffix == instruction.ZR { this.ExecuteZr(instruction_) } else if suffix == instruction.ZRC { this.ExecuteZrc(instruction_) } else if suffix == instruction.ZRCI { this.ExecuteZrci(instruction_) } else if suffix == instruction.S_RR || suffix == instruction.U_RR { this.ExecuteSRr(instruction_) } else if suffix == instruction.S_RRC || suffix == instruction.U_RRC { this.ExecuteSRrc(instruction_) } else if suffix == instruction.S_RRCI || suffix == instruction.U_RRCI { this.ExecuteSRrci(instruction_) } else if suffix == instruction.DRDICI { this.ExecuteDrdici(instruction_) } else if suffix == instruction.RRRI { this.ExecuteRrri(instruction_) } else if suffix == instruction.RRRICI { this.ExecuteRrrici(instruction_) } else if suffix == instruction.ZRRI { this.ExecuteZrri(instruction_) } else if suffix == instruction.ZRRICI { this.ExecuteZrrici(instruction_) } else if suffix == instruction.S_RRRI || suffix == instruction.U_RRRI { this.ExecuteSRrri(instruction_) } else if suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI { this.ExecuteSRrrici(instruction_) } else if suffix == instruction.RIR { this.ExecuteRir(instruction_) } else if suffix == instruction.RIRC { this.ExecuteRirc(instruction_) } else if suffix == instruction.RIRCI { this.ExecuteRirci(instruction_) } else if suffix == instruction.ZIR { this.ExecuteZir(instruction_) } else if suffix == instruction.ZIRC { this.ExecuteZirc(instruction_) } else if suffix == instruction.ZIRCI { this.ExecuteZirci(instruction_) } else if suffix == instruction.S_RIRC || suffix == instruction.U_RIRC { this.ExecuteSRirc(instruction_) } else if suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI { this.ExecuteSRirci(instruction_) } else if suffix == instruction.R { this.ExecuteR(instruction_) } else if suffix == instruction.RCI { this.ExecuteRci(instruction_) } else if suffix == instruction.Z { this.ExecuteZ(instruction_) } else if suffix == instruction.ZCI { this.ExecuteZci(instruction_) } else if suffix == instruction.S_R || suffix == instruction.U_R { this.ExecuteSR(instruction_) } else if suffix == instruction.S_RCI || suffix == instruction.U_RCI { this.ExecuteSRci(instruction_) } else if suffix == instruction.CI { this.ExecuteCi(instruction_) } else if suffix == instruction.I { this.ExecuteI(instruction_) } else if suffix == instruction.DDCI { this.ExecuteDdci(instruction_) } else if suffix == instruction.ERRI { this.ExecuteErri(instruction_) } else if suffix == instruction.S_ERRI || suffix == instruction.U_ERRI { this.ExecuteSErri(instruction_) } else if suffix == instruction.EDRI { this.ExecuteEdri(instruction_) } else if suffix == instruction.ERII { this.ExecuteErii(instruction_) } else if suffix == instruction.ERIR { this.ExecuteErir(instruction_) } else if suffix == instruction.ERID { this.ExecuteErid(instruction_) } else if suffix == instruction.DMA_RRI { this.ExecuteDmaRri(instruction_) } else { err := errors.New("suffix is not valid") panic(err) } if this.verbose >= 2 { fmt.Println(this.PrintRegFile(thread)) } } func (this *Logic) ExecuteRici(instruction_ *instruction.Instruction) { if _, found := instruction_.RiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } op_code := instruction_.OpCode() if _, is_acquire_rici_op_code := instruction_.AcquireRiciOpCodes()[op_code]; is_acquire_rici_op_code { this.ExecuteAcquireRici(instruction_) } else if _, is_release_rici_op_code := instruction_.ReleaseRiciOpCodes()[op_code]; is_release_rici_op_code { this.ExecuteReleaseRici(instruction_) } else if _, is_boot_rici_op_code := instruction_.BootRiciOpCodes()[op_code]; is_boot_rici_op_code { this.ExecuteBootRici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAcquireRici(instruction_ *instruction.Instruction) { if _, found := instruction_.AcquireRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid acquire RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.UNSIGNED) imm := instruction_.Imm().Value() atomic_address := this.alu.AtomicAddressHash(ra, imm) can_acquire := this.atomic.CanAcquire(atomic_address) if can_acquire { this.atomic.Acquire(atomic_address, thread.ThreadId()) } thread.RegFile().ClearConditions() if can_acquire { this.SetAcquireCc(instruction_, 0) } else { this.SetAcquireCc(instruction_, 1) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } if can_acquire { this.SetFlags(instruction_, 0, false) } else { this.SetFlags(instruction_, 1, false) } } func (this *Logic) ExecuteReleaseRici(instruction_ *instruction.Instruction) { if _, found := instruction_.ReleaseRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid release RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.UNSIGNED) imm := instruction_.Imm().Value() atomic_address := this.alu.AtomicAddressHash(ra, imm) can_release := this.atomic.CanRelease(atomic_address, thread.ThreadId()) if can_release { this.atomic.Release(atomic_address, thread.ThreadId()) } thread.RegFile().ClearConditions() if can_release { this.SetAcquireCc(instruction_, 0) } else { this.SetAcquireCc(instruction_, 1) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } if can_release { this.SetFlags(instruction_, 0, false) } else { this.SetFlags(instruction_, 1, false) } } func (this *Logic) ExecuteBootRici(instruction_ *instruction.Instruction) { if _, found := instruction_.BootRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid boot RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.UNSIGNED) imm := instruction_.Imm().Value() thread_id := int(this.alu.AtomicAddressHash(ra, imm)) thread.RegFile().ClearConditions() op_code := instruction_.OpCode() if op_code == instruction.BOOT { can_boot := this.thread_scheduler.Boot(thread_id) if can_boot { this.SetBootCc(instruction_, ra, 0) this.SetFlags(instruction_, 0, false) } else { this.SetBootCc(instruction_, ra, 1) this.SetFlags(instruction_, 1, false) } } else if op_code == instruction.RESUME { can_resume := this.thread_scheduler.Awake(thread_id) if can_resume { this.SetBootCc(instruction_, ra, 0) this.SetFlags(instruction_, 0, false) } else { this.SetBootCc(instruction_, ra, 1) this.SetFlags(instruction_, 1, false) } } else { err := errors.New("op code is not valid") panic(err) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteRri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddRri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrRri(instruction_) } else if _, is_call_rri_op_code := instruction_.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.ExecuteCallRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteCallRri(instruction_ *instruction.Instruction) { if _, found := instruction_.CallRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid call RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if imm == 0 { result, carry, _ = this.alu.Add(ra, imm) } else { result, carry, _ = this.alu.Add(ra*iram_data_size, imm) } thread.RegFile().ClearConditions() pc := thread.RegFile().ReadPcReg() thread.RegFile().WriteGpReg(instruction_.Rc(), pc+iram_data_size) thread.RegFile().WritePcReg(result) this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRric(instruction_ *instruction.Instruction) { if _, found := instruction_.RricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rric_op_code := instruction_.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.ExecuteAddRric(instruction_) } else if _, is_asrc_rric_op_code := instruction_.AsrRricOpCodes()[op_code]; is_asrc_rric_op_code { this.ExecuteAsrRric(instruction_) } else if _, is_sub_rric_op_code := instruction_.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.ExecuteSubRric(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRric(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrRric(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubRric(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, imm, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddRrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndRrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrRrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubRrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.RRIF { err := errors.New("suffix is not RRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } else if instruction_.Suffix() != instruction.RRR { err := errors.New("suffix is not RRR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, rb, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() if op_code != instruction.CALL { thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() } else { config_loader := new(misc.ConfigLoader) config_loader.Init() pc := thread.RegFile().ReadPcReg() iram_data_size := int64(config_loader.IramDataWidth() / 8) thread.RegFile().WriteGpReg(instruction_.Rc(), pc+iram_data_size) thread.RegFile().WritePcReg(result) } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrc_op_code := instruction_.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { this.ExecuteAddRrrc(instruction_) } else if _, is_rsub_rrrc_op_code := instruction_.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { this.ExecuteRsubRrrc(instruction_) } else if _, is_sub_rrrc_op_code := instruction_.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { this.ExecuteSubRrrc(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRsubRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, ra, rb, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSubRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, rb, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrci_op_code := instruction_.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { this.ExecuteAddRrrci(instruction_) } else if _, is_and_rrrci_op_code := instruction_.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { this.ExecuteAndRrrci(instruction_) } else if _, is_asr_rrrci_op_code := instruction_.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { this.ExecuteAsrRrrci(instruction_) } else if _, is_mul_rrrci_op_code := instruction_.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { this.ExecuteMulRrrci(instruction_) } else if _, is_rsub_rrrci_op_code := instruction_.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { this.ExecuteRsubRrrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, rb) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.MulRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetMulNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRsubRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, overflow = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, rb, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddZri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrZri(instruction_) } else if _, is_call_rri_op_code := instruction_.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.ExecuteCallZri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrZri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteCallZri(instruction_ *instruction.Instruction) { if _, found := instruction_.CallRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid call RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if imm == 0 { result, carry, _ = this.alu.Add(ra, imm) } else { result, carry, _ = this.alu.Add(ra*iram_data_size, imm) } thread.RegFile().ClearConditions() thread.RegFile().WritePcReg(result) this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZric(instruction_ *instruction.Instruction) { if _, found := instruction_.RricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rric_op_code := instruction_.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.ExecuteAddZric(instruction_) } else if _, is_asrc_rric_op_code := instruction_.AsrRricOpCodes()[op_code]; is_asrc_rric_op_code { this.ExecuteAsrZric(instruction_) } else if _, is_sub_rric_op_code := instruction_.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.ExecuteSubZric(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZric(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrZric(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubZric(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, imm, result, carry, overflow) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddZrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndZrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrZrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubZrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIF { err := errors.New("suffix is not ZRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } else if instruction_.Suffix() != instruction.ZRR { err := errors.New("suffix is not ZRR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, rb, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() if op_code != instruction.CALL { thread.RegFile().IncrementPcReg() } else { thread.RegFile().WritePcReg(result) } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrc_op_code := instruction_.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { this.ExecuteAddZrrc(instruction_) } else if _, is_rsub_rrrc_op_code := instruction_.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { this.ExecuteRsubZrrc(instruction_) } else if _, is_sub_rrrc_op_code := instruction_.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { this.ExecuteSubZrrc(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRsubZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, ra, rb, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSubZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, rb, result, carry, overflow) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrci_op_code := instruction_.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { this.ExecuteAddZrrci(instruction_) } else if _, is_and_rrrci_op_code := instruction_.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { this.ExecuteAndZrrci(instruction_) } else if _, is_asr_rrrci_op_code := instruction_.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { this.ExecuteAsrZrrci(instruction_) } else if _, is_mul_rrrci_op_code := instruction_.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { this.ExecuteMulZrrci(instruction_) } else if _, is_rsub_rrrci_op_code := instruction_.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { this.ExecuteRsubZrrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, rb) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.MulRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetMulNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRsubZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, overflow = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, rb, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddSRri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrSRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRric(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRric is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddSRrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndSRrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrSRrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubSRrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRIF && instruction_.Suffix() != instruction.U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRIF { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRIF { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrr(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrr is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrci is not yet implemented") panic(err) } func (this *Logic) ExecuteRr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } else if instruction_.Suffix() != instruction.RR { err := errors.New("suffix is not RR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRC { err := errors.New("suffix is not RRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } op_code := instruction_.OpCode() if _, is_cao_rrci_op_code := instruction_.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { this.ExecuteCaoRrci(instruction_) } else if _, is_extsb_rrci_op_code := instruction_.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { this.ExecuteExtsbRrci(instruction_) } else if _, is_time_cfg_rrci_op_code := instruction_.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { this.ExecuteTimeCfgRrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteCaoRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.CaoRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid cao RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetCountNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteExtsbRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.ExtsbRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid extsb RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteTimeCfgRrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteTimeCfgRrci is not yet implemented") panic(err) } func (this *Logic) ExecuteZr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } else if instruction_.Suffix() != instruction.ZR { err := errors.New("suffix is not ZR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteZrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRC { err := errors.New("suffix is not RRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } op_code := instruction_.OpCode() if _, is_cao_rrci_op_code := instruction_.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { this.ExecuteCaoZrci(instruction_) } else if _, is_extsb_rrci_op_code := instruction_.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { this.ExecuteExtsbZrci(instruction_) } else if _, is_time_cfg_rrci_op_code := instruction_.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { this.ExecuteTimeCfgZrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteCaoZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.CaoRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid cao RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetCountNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteExtsbZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.ExtsbRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid extsb RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteTimeCfgZrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteTimeCfgZrci is not yet implemented") panic(err) } func (this *Logic) ExecuteSRr(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRr is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrci is not yet implemented") panic(err) } func (this *Logic) ExecuteDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.DrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } op_code := instruction_.OpCode() if _, is_div_step_drdici_op_code := instruction_.DivStepDrdiciOpCodes()[op_code]; is_div_step_drdici_op_code { this.ExecuteDivStepDrdici(instruction_) } else if _, is_mul_step_drdici_op_code := instruction_.MulStepDrdiciOpCodes()[op_code]; is_mul_step_drdici_op_code { this.ExecuteMulStepDrdici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteDivStepDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.DivStepDrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid div_step DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), word.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), word.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() dbo_word := new(word.Word) dbo_word.Init(mram_data_width) dbo_word.SetValue(dbo) ra_shift_value := this.alu.Lsl(ra, imm) ra_shift_word := new(word.Word) ra_shift_word.Init(mram_data_width) ra_shift_word.SetValue(ra_shift_value) result, _, _ := this.alu.Sub(dbo, ra_shift_value) var dce int64 var dco int64 if dbo_word.Value(word.UNSIGNED) >= ra_shift_word.Value(word.UNSIGNED) { dce = this.alu.Lsl1(dbe, 1) dco = result } else { dce = this.alu.Lsl(dbe, 1) dco = thread.RegFile().ReadGpReg(instruction_.Dc().OddRegDescriptor(), word.SIGNED) } thread.RegFile().ClearConditions() this.SetDivCc(instruction_, ra) thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dce) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dco) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulStepDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.MulStepDrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul_step DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), word.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), word.SIGNED) imm := instruction_.Imm().Value() result1 := this.alu.Lsr(dbe, 1) result2, _, _ := this.alu.Sub(this.alu.And(dbe, 1), 1) var dco int64 if result2 == 0 { dco, _, _ = this.alu.Add(dbo, this.alu.Lsl(ra, imm)) } else { dco = thread.RegFile().ReadGpReg(instruction_.Dc().OddRegDescriptor(), word.SIGNED) } dce := this.alu.Lsr(dbe, 1) thread.RegFile().ClearConditions() this.SetBootCc(instruction_, ra, result1) thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dce) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dco) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result1, false) } func (this *Logic) ExecuteRrri(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRI { err := errors.New("suffix is not RRRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetDivNzCc(instruction_, ra) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrri(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetDivNzCc(instruction_, ra) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrri is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrici(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrici is not yet implemented") panic(err) } func (this *Logic) ExecuteRir(instruction_ *instruction.Instruction) { if _, found := instruction_.RirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } else if instruction_.Suffix() != instruction.RIR { err := errors.New("suffix is not RIR") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRirc(instruction_ *instruction.Instruction) { if _, found := instruction_.RircOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } else if instruction_.Suffix() != instruction.RIRC { err := errors.New("suffix is not RIRC") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, imm, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRirci(instruction_ *instruction.Instruction) { if _, found := instruction_.RirciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, imm, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZir(instruction_ *instruction.Instruction) { if _, found := instruction_.RirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } else if instruction_.Suffix() != instruction.ZIR { err := errors.New("suffix is not ZIR") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZirc(instruction_ *instruction.Instruction) { if _, found := instruction_.RircOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, imm, ra, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZirci(instruction_ *instruction.Instruction) { if _, found := instruction_.RirciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, imm, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRirc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRirc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRirci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRirci is not yet implemented") panic(err) } func (this *Logic) ExecuteR(instruction_ *instruction.Instruction) { err := errors.New("ExecuteR is not yet implemented") panic(err) } func (this *Logic) ExecuteRci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteRci is not yet implemented") panic(err) } func (this *Logic) ExecuteZ(instruction_ *instruction.Instruction) { if _, found := instruction_.ROpCodes()[instruction_.OpCode()]; !found && instruction_.OpCode() != instruction.NOP { err := errors.New("op code is not a valid R op code") panic(err) } else if instruction_.Suffix() != instruction.Z { err := errors.New("suffix is not Z") panic(err) } thread := this.scoreboard[instruction_] thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteZci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteZci is not yet implemented") panic(err) } func (this *Logic) ExecuteSR(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSR is not yet implemented") panic(err) } func (this *Logic) ExecuteSRci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRci is not yet implemented") panic(err) } func (this *Logic) ExecuteCi(instruction_ *instruction.Instruction) { if _, found := instruction_.CiOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } else if instruction_.Suffix() != instruction.CI { err := errors.New("suffix is not CI") panic(err) } thread := this.scoreboard[instruction_] this.thread_scheduler.Sleep(thread.ThreadId()) thread.RegFile().ClearConditions() if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteI(instruction_ *instruction.Instruction) { err := errors.New("ExecuteI is not yet implemented") panic(err) } func (this *Logic) ExecuteDdci(instruction_ *instruction.Instruction) { if _, found := instruction_.DdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } op_code := instruction_.OpCode() if _, is_movd_ddci_op_code := instruction_.MovdDdciOpCodes()[op_code]; is_movd_ddci_op_code { this.ExecuteMovdDdci(instruction_) } else if _, is_swapd_ddci_op_code := instruction_.SwapdDdciOpCodes()[op_code]; is_swapd_ddci_op_code { this.ExecuteSwapdDdciRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteMovdDdci(instruction_ *instruction.Instruction) { if _, found := instruction_.MovdDdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid movd DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } thread := this.scoreboard[instruction_] dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), word.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), word.SIGNED) thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dbe) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dbo) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteSwapdDdciRri(instruction_ *instruction.Instruction) { if _, found := instruction_.SwapdDdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid movd DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } thread := this.scoreboard[instruction_] dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), word.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), word.SIGNED) thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dbo) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dbe) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteErri(instruction_ *instruction.Instruction) { if _, found := instruction_.ErriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } else if instruction_.Suffix() != instruction.ERRI { err := errors.New("suffix is not ERRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) off := instruction_.Off().Value() address, _, _ := this.alu.Add(ra, off) var result int64 op_code := instruction_.OpCode() if op_code == instruction.LBS { result = this.operand_collector.Lbs(address) } else if op_code == instruction.LBU { result = this.operand_collector.Lbu(address) } else if op_code == instruction.LHS { result = this.operand_collector.Lhs(address) } else if op_code == instruction.LHU { result = this.operand_collector.Lhu(address) } else if op_code == instruction.LW { result = this.operand_collector.Lw(address) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteSErri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSErri is not yet implemented") panic(err) } func (this *Logic) ExecuteEdri(instruction_ *instruction.Instruction) { if _, found := instruction_.EdriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } else if instruction_.Suffix() != instruction.EDRI { err := errors.New("suffix is not EDRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) off := instruction_.Off().Value() address, _, _ := this.alu.Add(ra, off) var even int64 var odd int64 op_code := instruction_.OpCode() if op_code == instruction.LD { even, odd = this.operand_collector.Ld(address) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErii(instruction_ *instruction.Instruction) { if _, found := instruction_.EriiOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } else if instruction_.Suffix() != instruction.ERII { err := errors.New("suffix is not ERII") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) off := instruction_.Off().Value() imm := instruction_.Imm().Value() address, _, _ := this.alu.Add(ra, off) op_code := instruction_.OpCode() if op_code == instruction.SB { this.operand_collector.Sb(address, imm) } else if op_code == instruction.SB_ID { this.operand_collector.Sb(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SH { this.operand_collector.Sh(address, imm) } else if op_code == instruction.SH_ID { this.operand_collector.Sh(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SW { this.operand_collector.Sw(address, imm) } else if op_code == instruction.SW_ID { this.operand_collector.Sw(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SD { even, odd := this.alu.UnsignedExtension(imm) this.operand_collector.Sd(address, even, odd) } else if op_code == instruction.SD_ID { even, odd := this.alu.UnsignedExtension(this.alu.Or(int64(thread.ThreadId()), imm)) this.operand_collector.Sd(address, even, odd) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErir(instruction_ *instruction.Instruction) { if _, found := instruction_.ErirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } else if instruction_.Suffix() != instruction.ERIR { err := errors.New("suffix is not ERIR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) off := instruction_.Off().Value() rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) address, _, _ := this.alu.Add(ra, off) config_loader := new(misc.ConfigLoader) config_loader.Init() rb_word := new(word.Word) rb_word.Init(config_loader.MramDataWidth()) rb_word.SetValue(rb) op_code := instruction_.OpCode() if op_code == instruction.SB { this.operand_collector.Sb(address, rb_word.BitSlice(word.UNSIGNED, 0, 8)) } else if op_code == instruction.SH { this.operand_collector.Sh(address, rb_word.BitSlice(word.UNSIGNED, 0, 16)) } else if op_code == instruction.SW { this.operand_collector.Sw(address, rb_word.BitSlice(word.UNSIGNED, 0, 32)) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErid(instruction_ *instruction.Instruction) { if _, found := instruction_.EridOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } else if instruction_.Suffix() != instruction.ERID { err := errors.New("suffix is not ERID") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) off := instruction_.Off().Value() even, odd := thread.RegFile().ReadPairReg(instruction_.Db(), word.SIGNED) address, _, _ := this.alu.Add(ra, off) op_code := instruction_.OpCode() if op_code == instruction.SD { this.operand_collector.Sd(address, even, odd) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.DmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } op_code := instruction_.OpCode() if _, is_ldma_dma_rri_op_code := instruction_.LdmaDmaRriOpCodes()[op_code]; is_ldma_dma_rri_op_code { this.ExecuteLdmaDmaRri(instruction_) } else if _, is_ldmai_dma_rri_op_code := instruction_.LdmaiDmaRriOpCodes()[op_code]; is_ldmai_dma_rri_op_code { this.ExecuteLdmaiDmaRri(instruction_) } else if _, is_sdma_dma_rri_op_code := instruction_.SdmaDmaRriOpCodes()[op_code]; is_sdma_dma_rri_op_code { this.ExecuteSdmaDmaRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteLdmaDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.LdmaDmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ldma DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() wram_end_address := config_loader.WramOffset() + config_loader.WramSize() wram_end_address_width := int(math.Floor(math.Log2(float64(wram_end_address))) + 1) wram_mask := this.Pow2(wram_end_address_width) - 1 wram_address := this.alu.And(ra, wram_mask) mram_end_address := config_loader.MramOffset() + config_loader.MramSize() mram_end_address_width := int(math.Floor(math.Log2(float64(mram_end_address))) + 1) mram_mask := this.Pow2(mram_end_address_width) - 1 mram_address := this.alu.And(rb, mram_mask) size := (1 + this.alu.And(imm+this.alu.And(this.alu.Lsr(ra, 24), 255), 255)) * this.min_access_granularity this.dma.TransferFromMramToWram(wram_address, mram_address, size, instruction_) thread.RegFile().ClearConditions() } func (this *Logic) ExecuteLdmaiDmaRri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteLdmaiDmaRri is not yet implemented") panic(err) } func (this *Logic) ExecuteSdmaDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.SdmaDmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sdma DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), word.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), word.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() wram_end_address := config_loader.WramOffset() + config_loader.WramSize() wram_end_address_width := int(math.Floor(math.Log2(float64(wram_end_address))) + 1) wram_mask := this.Pow2(wram_end_address_width) - 1 wram_address := this.alu.And(ra, wram_mask) mram_end_address := config_loader.MramOffset() + config_loader.MramSize() mram_end_address_width := int(math.Floor(math.Log2(float64(mram_end_address))) + 1) mram_mask := this.Pow2(mram_end_address_width) - 1 mram_address := this.alu.And(rb, mram_mask) size := (1 + this.alu.And(imm+this.alu.And(this.alu.Lsr(ra, 24), 255), 255)) * this.min_access_granularity this.dma.TransferFromWramToMram(wram_address, mram_address, size, instruction_) thread.RegFile().ClearConditions() } func (this *Logic) SetAcquireCc(instruction_ *instruction.Instruction, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } } func (this *Logic) SetAddNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() result_word := new(word.Word) result_word.Init(config_loader.MramDataWidth()) result_word.SetValue(result) if result_word.Bit(6) { thread.RegFile().SetCondition(cc.NC5) } if result_word.Bit(7) { thread.RegFile().SetCondition(cc.NC6) } if result_word.Bit(8) { thread.RegFile().SetCondition(cc.NC7) } if result_word.Bit(9) { thread.RegFile().SetCondition(cc.NC8) } if result_word.Bit(10) { thread.RegFile().SetCondition(cc.NC9) } if result_word.Bit(11) { thread.RegFile().SetCondition(cc.NC10) } if result_word.Bit(12) { thread.RegFile().SetCondition(cc.NC11) } if result_word.Bit(13) { thread.RegFile().SetCondition(cc.NC12) } if result_word.Bit(14) { thread.RegFile().SetCondition(cc.NC13) } if result_word.Bit(15) { thread.RegFile().SetCondition(cc.NC14) } } func (this *Logic) SetBootCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetCountNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() if result == int64(config_loader.MramDataWidth()) { thread.RegFile().SetCondition(cc.MAX) } else { thread.RegFile().SetCondition(cc.NMAX) } } func (this *Logic) SetDivCc(instruction_ *instruction.Instruction, operand1 int64) { thread := this.scoreboard[instruction_] if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetDivNzCc(instruction_ *instruction.Instruction, operand1 int64) { thread := this.scoreboard[instruction_] if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetExtSubSetCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) if word1.Value(word.UNSIGNED) < word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.LTU) } if word1.Value(word.UNSIGNED) <= word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.LEU) } if word1.Value(word.UNSIGNED) > word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.GTU) } if word1.Value(word.UNSIGNED) >= word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.GEU) } if word1.Value(word.SIGNED) < word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.LTS) } if word1.Value(word.SIGNED) <= word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.LES) } if word1.Value(word.SIGNED) > word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.GTS) } if word1.Value(word.SIGNED) >= word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.GES) } if carry || thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XLEU) } if carry || !thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XGTU) } if thread.RegFile().ReadFlagReg(instruction.ZERO) && (result < 0 || overflow) { thread.RegFile().SetCondition(cc.XLES) } if !thread.RegFile().ReadFlagReg(instruction.ZERO) && (result >= 0 || overflow) { thread.RegFile().SetCondition(cc.XGTS) } } func (this *Logic) SetImmShiftNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if result%2 == 0 { thread.RegFile().SetCondition(cc.E) } else { thread.RegFile().SetCondition(cc.O) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1%2 == 0 { thread.RegFile().SetCondition(cc.SE) } else { thread.RegFile().SetCondition(cc.SO) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetLogNzCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetLogSetCc(instruction_ *instruction.Instruction, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } } func (this *Logic) SetMulNzCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } if result < 256 { thread.RegFile().SetCondition(cc.SMALL) } else { thread.RegFile().SetCondition(cc.LARGE) } } func (this *Logic) SetSubNzCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(word.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(word.Word) word2.Init(mram_data_width) word2.SetValue(operand2) if word1.Value(word.UNSIGNED) < word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.LTU) } if word1.Value(word.UNSIGNED) <= word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.LEU) } if word1.Value(word.UNSIGNED) > word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.GTU) } if word1.Value(word.UNSIGNED) >= word2.Value(word.UNSIGNED) { thread.RegFile().SetCondition(cc.GEU) } if word1.Value(word.SIGNED) < word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.LTS) } if word1.Value(word.SIGNED) <= word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.LES) } if word1.Value(word.SIGNED) > word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.GTS) } if word1.Value(word.SIGNED) >= word2.Value(word.SIGNED) { thread.RegFile().SetCondition(cc.GES) } if carry || thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XLEU) } if carry || !thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XGTU) } if thread.RegFile().ReadFlagReg(instruction.ZERO) && (result < 0 || overflow) { thread.RegFile().SetCondition(cc.XLES) } if !thread.RegFile().ReadFlagReg(instruction.ZERO) && (result >= 0 || overflow) { thread.RegFile().SetCondition(cc.XGTS) } } func (this *Logic) SetSubSetCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } } func (this *Logic) SetFlags(instruction_ *instruction.Instruction, result int64, carry bool) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetFlag(instruction.ZERO) } else { thread.RegFile().ClearFlag(instruction.ZERO) } if carry { thread.RegFile().SetFlag(instruction.CARRY) } else { thread.RegFile().ClearFlag(instruction.CARRY) } } func (this *Logic) Pow2(exponent int) int64 { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } func (this *Logic) PrintRegFile(thread *Thread) string { config_loader := new(misc.ConfigLoader) config_loader.Init() lines := "" for i := 0; i < config_loader.NumGpRegisters(); i++ { gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(i) lines += fmt.Sprintf( "r%d: %d\n", i, thread.RegFile().ReadGpReg(gp_reg_descriptor, word.SIGNED), ) } return lines } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/operand_collector.go ================================================ package logic import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/abi/word" "uPIMulator/src/simulator/dpu/sram" ) type OperandCollector struct { wram *sram.Wram } func (this *OperandCollector) Init() { this.wram = nil } func (this *OperandCollector) Fini() { } func (this *OperandCollector) ConnectWram(wram *sram.Wram) { if this.wram != nil { err := errors.New("wram is already set") panic(err) } this.wram = wram } func (this *OperandCollector) Lbs(address int64) int64 { byte_stream := this.wram.Read(address, 1) value := int64(byte_stream.Get(0)) word_ := new(word.Word) word_.Init(8) word_.SetValue(value) return word_.Value(word.SIGNED) } func (this *OperandCollector) Lbu(address int64) int64 { byte_stream := this.wram.Read(address, 1) value := int64(byte_stream.Get(0)) word_ := new(word.Word) word_.Init(8) word_.SetValue(value) return word_.Value(word.UNSIGNED) } func (this *OperandCollector) Lhs(address int64) int64 { word_ := new(word.Word) word_.Init(16) word_.SetBitSlice(0, 8, this.Lbs(address)) word_.SetBitSlice(8, 16, this.Lbs(address+1)) return word_.Value(word.SIGNED) } func (this *OperandCollector) Lhu(address int64) int64 { word_ := new(word.Word) word_.Init(16) word_.SetBitSlice(0, 8, this.Lbu(address)) word_.SetBitSlice(8, 16, this.Lbu(address+1)) return word_.Value(word.UNSIGNED) } func (this *OperandCollector) Lw(address int64) int64 { word_ := new(word.Word) word_.Init(32) word_.SetBitSlice(0, 8, this.Lbu(address)) word_.SetBitSlice(8, 16, this.Lbu(address+1)) word_.SetBitSlice(16, 24, this.Lbu(address+2)) word_.SetBitSlice(24, 32, this.Lbu(address+3)) return word_.Value(word.UNSIGNED) } func (this *OperandCollector) Ld(address int64) (int64, int64) { return this.Lw(address + 4), this.Lw(address) } func (this *OperandCollector) Sb(address int64, value int64) { word_ := new(word.Word) word_.Init(8) word_.SetValue(value) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(word_.Value(word.UNSIGNED))) this.wram.Write(address, 1, byte_stream) } func (this *OperandCollector) Sh(address int64, value int64) { word_ := new(word.Word) word_.Init(16) word_.SetValue(value) this.Sb(address, word_.BitSlice(word.UNSIGNED, 0, 8)) this.Sb(address+1, word_.BitSlice(word.UNSIGNED, 8, 16)) } func (this *OperandCollector) Sw(address int64, value int64) { word_ := new(word.Word) word_.Init(32) word_.SetValue(value) this.Sb(address, word_.BitSlice(word.UNSIGNED, 0, 8)) this.Sb(address+1, word_.BitSlice(word.UNSIGNED, 8, 16)) this.Sb(address+2, word_.BitSlice(word.UNSIGNED, 16, 24)) this.Sb(address+3, word_.BitSlice(word.UNSIGNED, 24, 32)) } func (this *OperandCollector) Sd(address int64, even int64, odd int64) { this.Sw(address+4, even) this.Sw(address, odd) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/pipeline.go ================================================ package logic import ( "errors" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/misc" ) type Pipeline struct { num_pipeline_stages int input_q *InstructionQ wait_q *InstructionQ ready_q *InstructionQ } func (this *Pipeline) Init(command_line_parser *misc.CommandLineParser) { this.num_pipeline_stages = int(command_line_parser.IntParameter("num_pipeline_stages")) this.input_q = new(InstructionQ) this.input_q.Init(1, 0) this.wait_q = new(InstructionQ) this.wait_q.Init(this.num_pipeline_stages-1, 0) for this.wait_q.CanPush(1) { this.wait_q.Push(nil) } this.ready_q = new(InstructionQ) this.ready_q.Init(1, 0) for this.ready_q.CanPush(1) { this.ready_q.Push(nil) } } func (this *Pipeline) Fini() { this.input_q.Fini() for this.wait_q.CanPop(1) { if this.wait_q.Pop() != nil { err := errors.New("wait queue is not empty") panic(err) } } this.wait_q.Fini() for this.ready_q.CanPop(1) { if this.ready_q.Pop() != nil { err := errors.New("ready queue is not empty") panic(err) } } this.ready_q.Fini() } func (this *Pipeline) IsEmpty() bool { return this.IsInputQEmpty() && this.IsWaitQEmpty() && this.IsReadyQEmpty() } func (this *Pipeline) IsInputQEmpty() bool { return this.input_q.IsEmpty() } func (this *Pipeline) IsWaitQEmpty() bool { if this.wait_q.IsEmpty() { return true } else { for i := 0; this.wait_q.CanPop(i + 1); i++ { instruction_, _ := this.wait_q.Front(i) if instruction_ != nil { return false } } return true } } func (this *Pipeline) IsReadyQEmpty() bool { if this.ready_q.IsEmpty() { return true } else { for i := 0; this.ready_q.CanPop(i + 1); i++ { instruction_, _ := this.ready_q.Front(i) if instruction_ != nil { return false } } return true } } func (this *Pipeline) CanPush() bool { return this.input_q.CanPush(1) } func (this *Pipeline) Push(instruction_ *instruction.Instruction) { if !this.CanPush() { err := errors.New("pipeline cannot be pushed") panic(err) } else if instruction_ == nil { err := errors.New("instruction == nil") panic(err) } this.input_q.Push(instruction_) } func (this *Pipeline) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Pipeline) Pop() *instruction.Instruction { if !this.CanPop() { err := errors.New("pipeline cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Pipeline) Cycle() { this.ServiceInputQ() this.ServiceWaitQ() this.input_q.Cycle() this.wait_q.Cycle() this.ready_q.Cycle() } func (this *Pipeline) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) { instruction_ := this.input_q.Pop() this.wait_q.Push(instruction_) } else if this.wait_q.CanPush(1) { this.wait_q.Push(nil) } } func (this *Pipeline) ServiceWaitQ() { if this.wait_q.CanPop(1) && this.ready_q.CanPush(1) { instruction_ := this.wait_q.Pop() this.ready_q.Push(instruction_) } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/reg_set.go ================================================ package logic import ( "errors" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" ) type RegSet struct { thread_id int prev_write_gp_reg_set map[*reg_descriptor.GpRegDescriptor]bool cur_read_gp_reg_set map[*reg_descriptor.GpRegDescriptor]bool } func (this *RegSet) Init(thread_id int) { if thread_id < 0 { err := errors.New("thread ID < 0") panic(err) } this.thread_id = thread_id this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } func (this *RegSet) ThreadId() int { return this.thread_id } func (this *RegSet) CollectReadGpRegs(instruction_ *instruction.Instruction) { suffix := instruction_.Suffix() if suffix == instruction.RICI || suffix == instruction.RRI || suffix == instruction.RRIC || suffix == instruction.RRICI || suffix == instruction.RRIF || suffix == instruction.ZRI || suffix == instruction.ZRIC || suffix == instruction.ZRICI || suffix == instruction.ZRIF || suffix == instruction.S_RRI || suffix == instruction.U_RRI || suffix == instruction.S_RRIC || suffix == instruction.U_RRIC || suffix == instruction.S_RRICI || suffix == instruction.U_RRICI || suffix == instruction.S_RRIF || suffix == instruction.U_RRIF || suffix == instruction.RR || suffix == instruction.RRC || suffix == instruction.RRCI || suffix == instruction.ZR || suffix == instruction.ZRC || suffix == instruction.ZRCI || suffix == instruction.S_RR || suffix == instruction.U_RR || suffix == instruction.S_RRC || suffix == instruction.U_RRC || suffix == instruction.S_RRCI || suffix == instruction.U_RRCI || suffix == instruction.RIR || suffix == instruction.RIRC || suffix == instruction.RIRCI || suffix == instruction.ZIR || suffix == instruction.ZIRC || suffix == instruction.ZIRCI || suffix == instruction.S_RIRC || suffix == instruction.U_RIRC || suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI || suffix == instruction.ERRI || suffix == instruction.S_ERRI || suffix == instruction.U_ERRI || suffix == instruction.EDRI || suffix == instruction.ERII { if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true } else { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } } else if suffix == instruction.RRR || suffix == instruction.RRRC || suffix == instruction.RRRCI || suffix == instruction.ZRR || suffix == instruction.ZRRC || suffix == instruction.ZRRCI || suffix == instruction.S_RRR || suffix == instruction.U_RRR || suffix == instruction.S_RRRC || suffix == instruction.U_RRRC || suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI || suffix == instruction.RRRI || suffix == instruction.RRRICI || suffix == instruction.ZRRI || suffix == instruction.ZRRICI || suffix == instruction.S_RRRI || suffix == instruction.U_RRRI || suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI || suffix == instruction.ERIR || suffix == instruction.DMA_RRI { if instruction_.Ra().IsGpRegDescriptor() && instruction_.Rb().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Rb().GpRegDescriptor()] = true } else if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true } else if instruction_.Rb().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Rb().GpRegDescriptor()] = true } else { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } } else if suffix == instruction.DRDICI || suffix == instruction.ERID { if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } else { this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } } else if suffix == instruction.R || suffix == instruction.RCI || suffix == instruction.Z || suffix == instruction.ZCI || suffix == instruction.S_R || suffix == instruction.U_R || suffix == instruction.S_RCI || suffix == instruction.U_RCI || suffix == instruction.CI || suffix == instruction.I { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } else if suffix == instruction.DDCI { this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } else { err := errors.New("suffix is not valid") panic(err) } } func (this *RegSet) CollectWriteGpRegs(instruction_ *instruction.Instruction) { suffix := instruction_.Suffix() if suffix == instruction.RICI || suffix == instruction.ZRI || suffix == instruction.ZRIC || suffix == instruction.ZRICI || suffix == instruction.ZRIF || suffix == instruction.ZRR || suffix == instruction.ZRRC || suffix == instruction.ZRRCI || suffix == instruction.ZR || suffix == instruction.ZRC || suffix == instruction.ZRCI || suffix == instruction.ZRRI || suffix == instruction.ZRRICI || suffix == instruction.ZIR || suffix == instruction.ZIRC || suffix == instruction.ZIRCI || suffix == instruction.Z || suffix == instruction.ZCI || suffix == instruction.CI || suffix == instruction.I || suffix == instruction.ERII || suffix == instruction.ERIR || suffix == instruction.ERID || suffix == instruction.DMA_RRI { this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } else if suffix == instruction.RRI || suffix == instruction.RRIC || suffix == instruction.RRICI || suffix == instruction.RRIF || suffix == instruction.RRR || suffix == instruction.RRRC || suffix == instruction.RRRCI || suffix == instruction.RR || suffix == instruction.RRC || suffix == instruction.RRCI || suffix == instruction.RRRI || suffix == instruction.RRRICI || suffix == instruction.RIR || suffix == instruction.RIRC || suffix == instruction.RIRCI || suffix == instruction.R || suffix == instruction.RCI || suffix == instruction.ERRI { this.prev_write_gp_reg_set[instruction_.Rc()] = true } else if suffix == instruction.S_RRI || suffix == instruction.U_RRI || suffix == instruction.S_RRIC || suffix == instruction.U_RRIC || suffix == instruction.S_RRICI || suffix == instruction.U_RRICI || suffix == instruction.S_RRIF || suffix == instruction.U_RRIF || suffix == instruction.S_RRR || suffix == instruction.U_RRR || suffix == instruction.S_RRRC || suffix == instruction.U_RRRC || suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI || suffix == instruction.S_RR || suffix == instruction.U_RR || suffix == instruction.S_RRC || suffix == instruction.U_RRC || suffix == instruction.S_RRCI || suffix == instruction.U_RRCI || suffix == instruction.DRDICI || suffix == instruction.S_RRRI || suffix == instruction.U_RRRI || suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI || suffix == instruction.S_RIRC || suffix == instruction.U_RIRC || suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI || suffix == instruction.S_R || suffix == instruction.U_R || suffix == instruction.DDCI || suffix == instruction.S_ERRI || suffix == instruction.U_ERRI || suffix == instruction.EDRI { this.prev_write_gp_reg_set[instruction_.Dc().EvenRegDescriptor()] = true this.prev_write_gp_reg_set[instruction_.Dc().OddRegDescriptor()] = true } else { err := errors.New("suffix is not valid") panic(err) } } func (this *RegSet) Clear() { this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool, 0) } func (this *RegSet) RegIndices() map[int]bool { reg_indices := make(map[int]bool, 0) for gp_reg_descriptor, _ := range this.prev_write_gp_reg_set { reg_indices[gp_reg_descriptor.Index()] = true } for gp_reg_descriptor, _ := range this.cur_read_gp_reg_set { reg_indices[gp_reg_descriptor.Index()] = true } return reg_indices } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/thread.go ================================================ package logic import ( "errors" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu/reg" ) type ThreadState int const ( EMBRYO ThreadState = iota RUNNABLE SLEEP BLOCK ZOMBIE ) type Thread struct { thread_id int thread_state ThreadState reg_file *reg.RegFile issue_cycle int64 } func (this *Thread) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() if thread_id < 0 { err := errors.New("thread ID < 0") panic(err) } else if thread_id >= config_loader.MaxNumTasklets() { err := errors.New("thread ID >= max number of tasklets") panic(err) } this.thread_id = thread_id this.thread_state = EMBRYO this.reg_file = new(reg.RegFile) this.reg_file.Init(thread_id) this.issue_cycle = 0 } func (this *Thread) Fini() { if this.thread_state != ZOMBIE { err := errors.New("thread state is not zombie") panic(err) } } func (this *Thread) ThreadId() int { return this.thread_id } func (this *Thread) ThreadState() ThreadState { return this.thread_state } func (this *Thread) SetThreadState(thread_state ThreadState) { this.thread_state = thread_state } func (this *Thread) RegFile() *reg.RegFile { return this.reg_file } func (this *Thread) IssueCycle() int64 { return this.issue_cycle } func (this *Thread) IncrementIssueCycle() { this.issue_cycle++ } func (this *Thread) ResetIssueCycle() { this.issue_cycle = 0 } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/thread_q.go ================================================ package logic import ( "errors" ) type ThreadQ struct { size int timer int64 threads []*Thread cycles []int64 } func (this *ThreadQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.threads = make([]*Thread, 0) this.cycles = make([]int64, 0) } func (this *ThreadQ) Fini() { if !this.IsEmpty() { err := errors.New("thread queue is not empty") panic(err) } } func (this *ThreadQ) Size() int { return this.size } func (this *ThreadQ) Timer() int64 { return this.timer } func (this *ThreadQ) IsEmpty() bool { return len(this.threads) == 0 } func (this *ThreadQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.threads) >= num_items } else { return true } } func (this *ThreadQ) Push(thread *Thread) { if !this.CanPush(1) { err := errors.New("thread queue cannot be pushed") panic(err) } this.threads = append(this.threads, thread) this.cycles = append(this.cycles, this.timer) } func (this *ThreadQ) PushWithTimer(thread *Thread, timer int64) { if !this.CanPush(1) { err := errors.New("thread queue cannot be pushed") panic(err) } this.threads = append(this.threads, thread) this.cycles = append(this.cycles, timer) } func (this *ThreadQ) CanPop(num_items int) bool { if len(this.threads) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *ThreadQ) Pop() *Thread { if !this.CanPop(1) { err := errors.New("thread queue cannot be popped") panic(err) } thread := this.threads[0] this.threads = this.threads[1:] this.cycles = this.cycles[1:] return thread } func (this *ThreadQ) Front(pos int) (*Thread, int64) { if this.IsEmpty() { err := errors.New("thread queue is empty") panic(err) } return this.threads[pos], this.cycles[pos] } func (this *ThreadQ) Remove(pos int) { this.threads = append(this.threads[:pos], this.threads[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *ThreadQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/logic/thread_scheduler.go ================================================ package logic import ( "errors" "fmt" "uPIMulator/src/misc" ) type ThreadScheduler struct { channel_id int rank_id int dpu_id int num_revolver_scheduling_cycles int64 threads []*Thread thread_q *ThreadQ stat_factory *misc.StatFactory } func (this *ThreadScheduler) Init( channel_id int, rank_id int, dpu_id int, threads []*Thread, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.num_revolver_scheduling_cycles = command_line_parser.IntParameter( "num_revolver_scheduling_cycles", ) this.threads = threads this.thread_q = new(ThreadQ) this.thread_q.Init(len(this.threads), 0) for _, thread := range threads { this.thread_q.Push(thread) } name := fmt.Sprintf("ThreadScheduler[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *ThreadScheduler) Fini() { for this.thread_q.CanPop(1) { this.thread_q.Pop() } this.thread_q.Fini() } func (this *ThreadScheduler) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *ThreadScheduler) NumIssuableThreads() int { num_issuable_threads := 0 for _, thread := range this.threads { if thread.ThreadState() == RUNNABLE { num_issuable_threads++ } } return num_issuable_threads } func (this *ThreadScheduler) Schedule() *Thread { var is_blocked bool is_blocked = false for i := 0; i < this.thread_q.Size(); i++ { thread := this.thread_q.Pop() this.thread_q.Push(thread) if thread.IssueCycle() >= this.num_revolver_scheduling_cycles { if thread.ThreadState() == RUNNABLE { thread.ResetIssueCycle() this.stat_factory.Increment("breakdown_run", 1) return thread } else if thread.ThreadState() == BLOCK { is_blocked = true } } } if is_blocked { this.stat_factory.Increment("breakdown_dma", 1) } else { this.stat_factory.Increment("breakdown_etc", 1) } return nil } func (this *ThreadScheduler) Boot(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == EMBRYO { thread.SetThreadState(RUNNABLE) return true } else if thread_state == ZOMBIE { thread.SetThreadState(RUNNABLE) return true } else { err := errors.New("thread is not bootable") panic(err) } } func (this *ThreadScheduler) Sleep(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == RUNNABLE { thread.SetThreadState(SLEEP) return true } else { err := errors.New("thread is not sleepable") panic(err) } } func (this *ThreadScheduler) Block(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == RUNNABLE { thread.SetThreadState(BLOCK) return true } else { err := errors.New("thread is not blockable") panic(err) } } func (this *ThreadScheduler) Awake(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == EMBRYO { thread.SetThreadState(RUNNABLE) return true } else if thread_state == SLEEP { thread.SetThreadState(RUNNABLE) return true } else if thread_state == BLOCK { thread.SetThreadState(RUNNABLE) return true } else { err := errors.New("thread is not awakable") panic(err) } } func (this *ThreadScheduler) Shutdown(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == SLEEP { thread.SetThreadState(ZOMBIE) return true } else { err := errors.New("thread is not shotdownable") panic(err) } } func (this *ThreadScheduler) Cycle() { } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/condition_reg.go ================================================ package reg import ( "errors" "uPIMulator/src/linker/kernel/instruction/cc" ) type ConditionReg struct { conditions map[cc.Condition]bool } func (this *ConditionReg) Init() { this.conditions = make(map[cc.Condition]bool, 0) this.ClearConditions() } func (this *ConditionReg) Fini() { } func (this *ConditionReg) Condition(condition cc.Condition) bool { if condition == cc.TRUE { return true } else if condition == cc.FALSE { return false } else { return this.conditions[condition] } } func (this *ConditionReg) SetCondition(condition cc.Condition) { if condition == cc.TRUE || condition == cc.FALSE { err := errors.New("condition is true or false") panic(err) } this.conditions[condition] = true } func (this *ConditionReg) ClearCondition(condition cc.Condition) { if condition == cc.TRUE || condition == cc.FALSE { err := errors.New("condition is true or false") panic(err) } this.conditions[condition] = false } func (this *ConditionReg) ClearConditions() { for i := 0; i <= int(cc.LARGE); i++ { condition := cc.Condition(i) if condition == cc.TRUE || condition == cc.FALSE { continue } else { this.conditions[condition] = false } } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/exception_reg.go ================================================ package reg import ( "uPIMulator/src/linker/kernel/instruction" ) type ExceptionReg struct { exceptions map[instruction.Exception]bool } func (this *ExceptionReg) Init() { this.exceptions = make(map[instruction.Exception]bool, 0) this.ClearExceptions() } func (this *ExceptionReg) Fini() { } func (this *ExceptionReg) Exception(exception instruction.Exception) bool { return this.exceptions[exception] } func (this *ExceptionReg) SetException(exception instruction.Exception) { this.exceptions[exception] = true } func (this *ExceptionReg) ClearException(exception instruction.Exception) { this.exceptions[exception] = false } func (this *ExceptionReg) ClearExceptions() { for i := 0; i <= int(instruction.NOT_PROFILING); i++ { exception := instruction.Exception(i) this.exceptions[exception] = false } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/flag_reg.go ================================================ package reg import ( "uPIMulator/src/linker/kernel/instruction" ) type FlagReg struct { flags map[instruction.Flag]bool } func (this *FlagReg) Init() { this.flags = make(map[instruction.Flag]bool, 0) this.ClearFlags() } func (this *FlagReg) Fini() { } func (this *FlagReg) Flag(flag instruction.Flag) bool { return this.flags[flag] } func (this *FlagReg) SetFlag(flag instruction.Flag) { this.flags[flag] = true } func (this *FlagReg) ClearFlag(flag instruction.Flag) { this.flags[flag] = false } func (this *FlagReg) ClearFlags() { for i := 0; i <= int(instruction.CARRY); i++ { flag := instruction.Flag(i) this.flags[flag] = false } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/gp_reg.go ================================================ package reg import ( "uPIMulator/src/abi/word" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type GpReg struct { gp_reg_descriptor *reg_descriptor.GpRegDescriptor word *word.Word } func (this *GpReg) Init(index int) { this.gp_reg_descriptor = new(reg_descriptor.GpRegDescriptor) this.gp_reg_descriptor.Init(index) config_loader := new(misc.ConfigLoader) config_loader.Init() this.word = new(word.Word) this.word.Init(config_loader.MramDataWidth()) } func (this *GpReg) Fini() { } func (this *GpReg) Index() int { return this.gp_reg_descriptor.Index() } func (this *GpReg) Read(representation word.Representation) int64 { return this.word.Value(representation) } func (this *GpReg) Write(value int64) { this.word.SetValue(value) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/pc_reg.go ================================================ package reg import ( "uPIMulator/src/abi/word" "uPIMulator/src/misc" ) type PcReg struct { word *word.Word } func (this *PcReg) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.word = new(word.Word) this.word.Init(config_loader.AddressWidth()) } func (this *PcReg) Fini() { } func (this *PcReg) Read() int64 { return this.word.Value(word.UNSIGNED) } func (this *PcReg) Write(value int64) { this.word.SetValue(value) } func (this *PcReg) Increment() { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) this.Write(this.Read() + iram_data_size) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/reg_file.go ================================================ package reg import ( "uPIMulator/src/abi/word" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/linker/kernel/instruction/cc" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type RegFile struct { gp_regs []*GpReg sp_reg *SpReg pc_reg *PcReg condition_reg *ConditionReg flag_reg *FlagReg exception_reg *ExceptionReg } func (this *RegFile) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.gp_regs = make([]*GpReg, 0) for i := 0; i < config_loader.NumGpRegisters(); i++ { gp_reg := new(GpReg) gp_reg.Init(i) this.gp_regs = append(this.gp_regs, gp_reg) } this.sp_reg = new(SpReg) this.sp_reg.Init(thread_id) this.pc_reg = new(PcReg) this.pc_reg.Init() this.condition_reg = new(ConditionReg) this.condition_reg.Init() this.flag_reg = new(FlagReg) this.flag_reg.Init() this.exception_reg = new(ExceptionReg) this.exception_reg.Init() } func (this *RegFile) Fini() { for _, gp_reg := range this.gp_regs { gp_reg.Fini() } this.sp_reg.Fini() this.pc_reg.Fini() this.condition_reg.Fini() this.flag_reg.Fini() this.exception_reg.Fini() } func (this *RegFile) ReadGpReg( gp_reg_descriptor *reg_descriptor.GpRegDescriptor, representation word.Representation, ) int64 { return this.gp_regs[gp_reg_descriptor.Index()].Read(representation) } func (this *RegFile) ReadSpReg( sp_reg_descriptor *reg_descriptor.SpRegDescriptor, representation word.Representation, ) int64 { return this.sp_reg.Read(sp_reg_descriptor, representation) } func (this *RegFile) ReadPairReg( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, representation word.Representation, ) (int64, int64) { even := this.ReadGpReg(pair_reg_descriptor.EvenRegDescriptor(), representation) odd := this.ReadGpReg(pair_reg_descriptor.OddRegDescriptor(), word.UNSIGNED) return even, odd } func (this *RegFile) ReadSrcReg( src_reg_descriptor *reg_descriptor.SrcRegDescriptor, representation word.Representation, ) int64 { if src_reg_descriptor.IsGpRegDescriptor() { return this.ReadGpReg(src_reg_descriptor.GpRegDescriptor(), representation) } else { return this.ReadSpReg(src_reg_descriptor.SpRegDescriptor(), representation) } } func (this *RegFile) ReadPcReg() int64 { return this.pc_reg.Read() } func (this *RegFile) ReadConditionReg(condition cc.Condition) bool { return this.condition_reg.Condition(condition) } func (this *RegFile) ReadFlagReg(flag instruction.Flag) bool { return this.flag_reg.Flag(flag) } func (this *RegFile) ReadExceptionReg(exception instruction.Exception) bool { return this.exception_reg.Exception(exception) } func (this *RegFile) WriteGpReg(gp_reg_descriptor *reg_descriptor.GpRegDescriptor, value int64) { this.gp_regs[gp_reg_descriptor.Index()].Write(value) } func (this *RegFile) WritePairReg( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, even int64, odd int64, ) { this.WriteGpReg(pair_reg_descriptor.EvenRegDescriptor(), even) this.WriteGpReg(pair_reg_descriptor.OddRegDescriptor(), odd) } func (this *RegFile) WritePcReg(value int64) { this.pc_reg.Write(value) } func (this *RegFile) IncrementPcReg() { this.pc_reg.Increment() } func (this *RegFile) SetCondition(condition cc.Condition) { this.condition_reg.SetCondition(condition) } func (this *RegFile) ClearCondition(condition cc.Condition) { this.condition_reg.ClearCondition(condition) } func (this *RegFile) ClearConditions() { this.condition_reg.ClearConditions() } func (this *RegFile) SetFlag(flag instruction.Flag) { this.flag_reg.SetFlag(flag) } func (this *RegFile) ClearFlag(flag instruction.Flag) { this.flag_reg.ClearFlag(flag) } func (this *RegFile) ClearFlags() { this.flag_reg.ClearFlags() } func (this *RegFile) SetException(exception instruction.Exception) { this.exception_reg.SetException(exception) } func (this *RegFile) ClearException(exception instruction.Exception) { this.exception_reg.ClearException(exception) } func (this *RegFile) ClearExceptions() { this.exception_reg.ClearExceptions() } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/reg/sp_reg.go ================================================ package reg import ( "errors" "uPIMulator/src/abi/word" "uPIMulator/src/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type SpReg struct { zero *word.Word one *word.Word lneg *word.Word mneg *word.Word id *word.Word id2 *word.Word id4 *word.Word id8 *word.Word } func (this *SpReg) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.zero = new(word.Word) this.zero.Init(config_loader.MramDataWidth()) this.zero.SetValue(0) this.one = new(word.Word) this.one.Init(config_loader.MramDataWidth()) this.one.SetValue(1) this.lneg = new(word.Word) this.lneg.Init(config_loader.MramDataWidth()) this.lneg.SetValue(-1) this.mneg = new(word.Word) this.mneg.Init(config_loader.MramDataWidth()) this.mneg.SetValue(int64(this.mneg.Width()) - 1) this.id = new(word.Word) this.id.Init(config_loader.MramDataWidth()) this.id.SetValue(int64(thread_id)) this.id2 = new(word.Word) this.id2.Init(config_loader.MramDataWidth()) this.id2.SetValue(int64(2 * thread_id)) this.id4 = new(word.Word) this.id4.Init(config_loader.MramDataWidth()) this.id4.SetValue(int64(4 * thread_id)) this.id8 = new(word.Word) this.id8.Init(config_loader.MramDataWidth()) this.id8.SetValue(int64(8 * thread_id)) } func (this *SpReg) Fini() { } func (this *SpReg) Read( sp_reg_descriptor *reg_descriptor.SpRegDescriptor, representation word.Representation, ) int64 { if *sp_reg_descriptor == reg_descriptor.ZERO { return this.zero.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ONE { return this.one.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.LNEG { return this.lneg.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.MNEG { return this.mneg.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID { return this.id.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID2 { return this.id2.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID4 { return this.id4.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID8 { return this.id8.Value(representation) } else { err := errors.New("sp reg descriptor is not valid") panic(err) } } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/sram/atomic.go ================================================ package sram import ( "errors" "uPIMulator/src/misc" ) type Atomic struct { address int64 size int64 locks []*Lock } func (this *Atomic) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.AtomicOffset() this.size = config_loader.AtomicSize() this.locks = make([]*Lock, 0) for i := int64(0); i < this.size; i++ { lock := new(Lock) lock.Init() this.locks = append(this.locks, lock) } } func (this *Atomic) Fini() { for _, lock := range this.locks { lock.Fini() } } func (this *Atomic) Address() int64 { return this.address } func (this *Atomic) Size() int64 { return this.size } func (this *Atomic) CanAcquire(address int64) bool { return this.locks[this.Index(address)].CanAcquire() } func (this *Atomic) Acquire(address int64, thread_id int) { this.locks[this.Index(address)].Acquire(thread_id) } func (this *Atomic) CanRelease(address int64, thread_id int) bool { return this.locks[this.Index(address)].CanRelease(thread_id) } func (this *Atomic) Release(address int64, thread_id int) { this.locks[this.Index(address)].Release(thread_id) } func (this *Atomic) Index(address int64) int { if address < this.address { err := errors.New("address < atomic offset") panic(err) } else if address >= this.address+this.size { err := errors.New("address >= atomic offset + atomic size") panic(err) } return int(address - this.address) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/sram/iram.go ================================================ package sram import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/linker/kernel/instruction" "uPIMulator/src/misc" ) type Iram struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Iram) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.IramOffset() this.size = config_loader.IramSize() this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < this.size; i++ { this.byte_stream.Append(0) } } func (this *Iram) Fini() { } func (this *Iram) Address() int64 { return this.address } func (this *Iram) Size() int64 { return this.size } func (this *Iram) Read(address int64) *instruction.Instruction { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < iram_data_size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } instruction_ := new(instruction.Instruction) instruction_.Decode(byte_stream) return instruction_ } func (this *Iram) Write(address int64, byte_stream *encoding.ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *Iram) Index(address int64) int { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if address < this.address { err := errors.New("address < IRAM offset") panic(err) } else if address+iram_data_size > this.address+this.size { err := errors.New("address >= IRAM offset + IRAM size") panic(err) } if (address-this.address)%iram_data_size != 0 { err := errors.New("addresses are not aligned with IRAM data size") panic(err) } return int(address - this.address) } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/sram/lock.go ================================================ package sram import ( "errors" ) type Lock struct { thread_id *int } func (this *Lock) Init() { this.thread_id = nil } func (this *Lock) Fini() { if this.thread_id != nil { err := errors.New("thread ID != nil") panic(err) } } func (this *Lock) CanAcquire() bool { return this.thread_id == nil } func (this *Lock) Acquire(thread_id int) { if !this.CanAcquire() { err := errors.New("lock cannot be acquired") panic(err) } this.thread_id = new(int) *this.thread_id = thread_id } func (this *Lock) CanRelease(thread_id int) bool { return this.thread_id == nil || *this.thread_id == thread_id } func (this *Lock) Release(thread_id int) { if !this.CanRelease(thread_id) { err := errors.New("lock cannot be released") panic(err) } this.thread_id = nil } ================================================ FILE: golang/uPIMulator/src/simulator/dpu/sram/wram.go ================================================ package sram import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" ) type Wram struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Wram) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.WramOffset() this.size = config_loader.WramSize() this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < this.size; i++ { this.byte_stream.Append(0) } } func (this *Wram) Fini() { } func (this *Wram) Address() int64 { return this.address } func (this *Wram) Size() int64 { return this.size } func (this *Wram) Read(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } return byte_stream } func (this *Wram) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *Wram) Index(address int64) int { if address < this.address { err := errors.New("address < WRAM offset") panic(err) } else if address >= this.address+this.size { err := errors.New("address >= WRAM offset + WRAM size") panic(err) } return int(address - this.address) } ================================================ FILE: golang/uPIMulator/src/simulator/host/channel_transfer_read_job.go ================================================ package host import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/simulator/channel" ) type ChannelTransferReadJob struct { channel_message *channel.ChannelMessage byte_streams []*encoding.ByteStream channel *channel.Channel } func (this *ChannelTransferReadJob) Init( channel_message *channel.ChannelMessage, byte_streams []*encoding.ByteStream, channel_ *channel.Channel, ) { if channel_message.ChannelOperation() != channel.READ { err := errors.New("channel operation is not read") panic(err) } this.channel_message = channel_message this.byte_streams = byte_streams this.channel = channel_ } func (this *ChannelTransferReadJob) Execute() { this.channel.Lock() this.channel.Push(this.channel_message) for !this.channel.CanPopChannelMessage(this.channel_message) { this.channel.Cycle() } this.channel.PopChannelMessage(this.channel_message) this.CompareByteStreams(this.byte_streams, this.channel_message.ByteStreams()) this.channel.Unlock() } func (this *ChannelTransferReadJob) CompareByteStreams( byte_streams_1 []*encoding.ByteStream, byte_streams_2 []*encoding.ByteStream, ) { if len(byte_streams_1) != len(byte_streams_2) { err := errors.New("byte streams 1's length != byte streams 2's length") panic(err) } for i := 0; i < len(byte_streams_1); i++ { byte_stream_1 := byte_streams_1[i] byte_stream_2 := byte_streams_2[i] if byte_stream_1.Size() != byte_stream_2.Size() { err := errors.New("byte stream 1's size != byte stream 2's size") panic(err) } for j := int64(0); j < byte_stream_1.Size(); j++ { if byte_stream_1.Get(int(j)) != byte_stream_2.Get(int(j)) { err := errors.New("bytes are different") panic(err) } } } } ================================================ FILE: golang/uPIMulator/src/simulator/host/channel_transfer_write_job.go ================================================ package host import ( "errors" "uPIMulator/src/simulator/channel" ) type ChannelTransferWriteJob struct { channel_message *channel.ChannelMessage channel *channel.Channel } func (this *ChannelTransferWriteJob) Init( channel_message *channel.ChannelMessage, channel_ *channel.Channel, ) { if channel_message.ChannelOperation() != channel.WRITE { err := errors.New("channel operation is not write") panic(err) } this.channel_message = channel_message this.channel = channel_ } func (this *ChannelTransferWriteJob) Execute() { this.channel.Lock() this.channel.Push(this.channel_message) for !this.channel.CanPopChannelMessage(this.channel_message) { this.channel.Cycle() } this.channel.PopChannelMessage(this.channel_message) this.channel.Unlock() } ================================================ FILE: golang/uPIMulator/src/simulator/host/chunk.go ================================================ package host import ( "errors" "strconv" "strings" "uPIMulator/src/abi/encoding" ) type ChunkType int const ( INPUT_DPU_HOST ChunkType = iota OUTPUT_DPU_HOST INPUT_DPU_MRAM_HEAP_POINTER_NAME OUTPUT_DPU_MRAM_HEAP_POINTER_NAME ) type Chunk struct { chunk_type ChunkType name *string offset *int64 execution int dpu_id int byte_stream *encoding.ByteStream } func (this *Chunk) Init(filename string, byte_stream *encoding.ByteStream) { if this.IsInputDpuHost(filename) { this.InitInputDpuHost(filename) } else if this.IsOutputDpuHost(filename) { this.InitOutputDpuHost(filename) } else if this.IsInputDpuMramHeapPointerName(filename) { this.InitInputDpuMramHeapPointerName(filename) } else if this.IsOutputDpuMramHeapPointerName(filename) { this.InitOutputDpuMramHeapPointerName(filename) } else { err := errors.New("filename cannot be parsed") panic(err) } this.byte_stream = byte_stream } func (this *Chunk) IsInputDpuHost(filename string) bool { words := strings.Split(strings.Split(filename, ".")[0], "_") if words[0] == "input" && !(words[1] == "dpu" && words[2] == "mram" && words[3] == "heap" && words[4] == "pointer" && words[5] == "name") { return true } else { return false } } func (this *Chunk) IsOutputDpuHost(filename string) bool { words := strings.Split(strings.Split(filename, ".")[0], "_") if words[0] == "output" && !(words[1] == "dpu" && words[2] == "mram" && words[3] == "heap" && words[4] == "pointer" && words[5] == "name") { return true } else { return false } } func (this *Chunk) IsInputDpuMramHeapPointerName(filename string) bool { words := strings.Split(strings.Split(filename, ".")[0], "_") if words[0] == "input" && words[1] == "dpu" && words[2] == "mram" && words[3] == "heap" && words[4] == "pointer" && words[5] == "name" { return true } else { return false } } func (this *Chunk) IsOutputDpuMramHeapPointerName(filename string) bool { words := strings.Split(strings.Split(filename, ".")[0], "_") if words[0] == "output" && words[1] == "dpu" && words[2] == "mram" && words[3] == "heap" && words[4] == "pointer" && words[5] == "name" { return true } else { return false } } func (this *Chunk) InitInputDpuHost(filename string) { if !this.IsInputDpuHost(filename) { err := errors.New("filename is not input DPU host") panic(err) } this.chunk_type = INPUT_DPU_HOST words := strings.Split(strings.Split(filename, ".")[0], "_") this.name = new(string) *this.name = strings.Join(words[1:len(words)-2], "_") var err error this.execution, err = strconv.Atoi(words[len(words)-2]) if err != nil { panic(err) } this.dpu_id, err = strconv.Atoi(words[len(words)-1]) if err != nil { panic(err) } } func (this *Chunk) InitOutputDpuHost(filename string) { if !this.IsOutputDpuHost(filename) { err := errors.New("filename is not output DPU host") panic(err) } this.chunk_type = OUTPUT_DPU_HOST words := strings.Split(strings.Split(filename, ".")[0], "_") this.name = new(string) *this.name = strings.Join(words[1:len(words)-2], "_") var err error this.execution, err = strconv.Atoi(words[len(words)-2]) if err != nil { panic(err) } this.dpu_id, err = strconv.Atoi(words[len(words)-1]) if err != nil { panic(err) } } func (this *Chunk) InitInputDpuMramHeapPointerName(filename string) { if !this.IsInputDpuMramHeapPointerName(filename) { err := errors.New("filename is not input DPU MRAM heap pointer name") panic(err) } this.chunk_type = INPUT_DPU_MRAM_HEAP_POINTER_NAME words := strings.Split(strings.Split(filename, ".")[0], "_") var err error this.offset = new(int64) *this.offset, err = strconv.ParseInt(words[len(words)-3], 10, 64) if err != nil { panic(err) } this.execution, err = strconv.Atoi(words[len(words)-2]) if err != nil { panic(err) } this.dpu_id, err = strconv.Atoi(words[len(words)-1]) if err != nil { panic(err) } } func (this *Chunk) InitOutputDpuMramHeapPointerName(filename string) { if !this.IsOutputDpuMramHeapPointerName(filename) { err := errors.New("filename is not output DPU MRAM heap pointer name") panic(err) } this.chunk_type = OUTPUT_DPU_MRAM_HEAP_POINTER_NAME words := strings.Split(strings.Split(filename, ".")[0], "_") var err error this.offset = new(int64) *this.offset, err = strconv.ParseInt(words[len(words)-3], 10, 64) if err != nil { panic(err) } this.execution, err = strconv.Atoi(words[len(words)-2]) if err != nil { panic(err) } this.dpu_id, err = strconv.Atoi(words[len(words)-1]) if err != nil { panic(err) } } func (this *Chunk) ChunkType() ChunkType { return this.chunk_type } func (this *Chunk) Name() string { if this.name == nil { err := errors.New("name == nil") panic(err) } return *this.name } func (this *Chunk) Offset() int64 { if this.offset == nil { err := errors.New("offset == nil") panic(err) } return *this.offset } func (this *Chunk) Execution() int { return this.execution } func (this *Chunk) DpuId() int { return this.dpu_id } func (this *Chunk) ByteStream() *encoding.ByteStream { return this.byte_stream } ================================================ FILE: golang/uPIMulator/src/simulator/host/cycle_job.go ================================================ package host import ( "uPIMulator/src/simulator/dpu" "uPIMulator/src/simulator/dpu/logic" ) type CycleJob struct { sys_end int64 dpu *dpu.Dpu } func (this *CycleJob) Init(sys_end int64, dpu_ *dpu.Dpu) { this.sys_end = sys_end this.dpu = dpu_ } func (this *CycleJob) Execute() { threads := this.dpu.Threads() for _, thread := range threads { if thread.RegFile().ReadPcReg() == this.sys_end && thread.ThreadState() == logic.SLEEP { this.dpu.ThreadScheduler().Shutdown(thread.ThreadId()) } } } ================================================ FILE: golang/uPIMulator/src/simulator/host/dma_transfer_to_atomic_job.go ================================================ package host import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" ) type DmaTransferToAtomicJob struct { atomic *encoding.ByteStream dpu *dpu.Dpu } func (this *DmaTransferToAtomicJob) Init(atomic *encoding.ByteStream, dpu_ *dpu.Dpu) { this.atomic = atomic this.dpu = dpu_ } func (this *DmaTransferToAtomicJob) Execute() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.dpu.Dma().TransferToAtomic(config_loader.AtomicOffset(), this.atomic) } ================================================ FILE: golang/uPIMulator/src/simulator/host/dma_transfer_to_iram_job.go ================================================ package host import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" ) type DmaTransferToIramJob struct { iram *encoding.ByteStream dpu *dpu.Dpu } func (this *DmaTransferToIramJob) Init(iram *encoding.ByteStream, dpu_ *dpu.Dpu) { this.iram = iram this.dpu = dpu_ } func (this *DmaTransferToIramJob) Execute() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.dpu.Dma().TransferToIram(config_loader.IramOffset(), this.iram) } ================================================ FILE: golang/uPIMulator/src/simulator/host/dma_transfer_to_mram_job.go ================================================ package host import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" ) type DmaTransferToMramJob struct { mram *encoding.ByteStream dpu *dpu.Dpu } func (this *DmaTransferToMramJob) Init(mram *encoding.ByteStream, dpu_ *dpu.Dpu) { this.mram = mram this.dpu = dpu_ } func (this *DmaTransferToMramJob) Execute() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.dpu.Dma().TransferToMram(config_loader.MramOffset(), this.mram) } ================================================ FILE: golang/uPIMulator/src/simulator/host/dma_transfer_to_wram_job.go ================================================ package host import ( "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" ) type DmaTransferToWramJob struct { wram *encoding.ByteStream dpu *dpu.Dpu } func (this *DmaTransferToWramJob) Init(wram *encoding.ByteStream, dpu_ *dpu.Dpu) { this.wram = wram this.dpu = dpu_ } func (this *DmaTransferToWramJob) Execute() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.dpu.Dma().TransferToWram(config_loader.WramOffset(), this.wram) } ================================================ FILE: golang/uPIMulator/src/simulator/host/host.go ================================================ package host import ( "errors" "os" "path/filepath" "strconv" "strings" "uPIMulator/src/abi/encoding" "uPIMulator/src/core" "uPIMulator/src/misc" "uPIMulator/src/simulator/channel" "uPIMulator/src/simulator/dpu" ) type Host struct { bin_dirpath string num_simulation_threads int benchmark string num_channels int num_ranks_per_channel int num_dpus_per_rank int num_tasklets int addresses map[string]int64 values map[string]int64 atomic *encoding.ByteStream iram *encoding.ByteStream wram *encoding.ByteStream mram *encoding.ByteStream num_executions int input_dpu_host []*Chunk output_dpu_host []*Chunk input_dpu_mram_heap_pointer_name []*Chunk output_dpu_mram_heap_pointer_name []*Chunk channels []*channel.Channel } func (this *Host) Init(command_line_parser *misc.CommandLineParser) { this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.num_simulation_threads = int(command_line_parser.IntParameter("num_simulation_threads")) this.benchmark = command_line_parser.StringParameter("benchmark") this.num_channels = int(command_line_parser.IntParameter("num_channels")) this.num_ranks_per_channel = int(command_line_parser.IntParameter("num_ranks_per_channel")) this.num_dpus_per_rank = int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.channels = make([]*channel.Channel, 0) this.InitAddresses() this.InitValues() this.InitAtomic() this.InitIram() this.InitWram() this.InitMram() this.InitNumExecutions() this.InitChunks() } func (this *Host) InitAddresses() { path := filepath.Join(this.bin_dirpath, "addresses.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() this.addresses = make(map[string]int64, 0) for _, line := range lines { words := strings.Split(line, ":") name := words[0] address, err := strconv.ParseInt(words[1][1:], 10, 64) if err != nil { panic(err) } this.addresses[name] = address } } func (this *Host) InitValues() { path := filepath.Join(this.bin_dirpath, "values.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() this.values = make(map[string]int64, 0) for _, line := range lines { words := strings.Split(line, ":") name := words[0] address, err := strconv.ParseInt(words[1][1:], 10, 64) if err != nil { panic(err) } this.values[name] = address } } func (this *Host) InitAtomic() { path := filepath.Join(this.bin_dirpath, "atomic.bin") this.atomic = this.InitByteStream(path) } func (this *Host) InitIram() { path := filepath.Join(this.bin_dirpath, "iram.bin") this.iram = this.InitByteStream(path) } func (this *Host) InitWram() { path := filepath.Join(this.bin_dirpath, "wram.bin") this.wram = this.InitByteStream(path) } func (this *Host) InitMram() { path := filepath.Join(this.bin_dirpath, "mram.bin") this.mram = this.InitByteStream(path) } func (this *Host) InitNumExecutions() { path := filepath.Join(this.bin_dirpath, "num_executions.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() if len(lines) != 1 { err := errors.New("lines' length != 1") panic(err) } var err error this.num_executions, err = strconv.Atoi(lines[0]) if err != nil { panic(err) } } func (this *Host) InitChunks() { entries, bin_dir_read_err := os.ReadDir(this.bin_dirpath) if bin_dir_read_err != nil { panic(bin_dir_read_err) } this.input_dpu_host = make([]*Chunk, 0) this.output_dpu_host = make([]*Chunk, 0) this.input_dpu_mram_heap_pointer_name = make([]*Chunk, 0) this.output_dpu_mram_heap_pointer_name = make([]*Chunk, 0) for _, entry := range entries { filename := entry.Name() words := strings.Split(strings.Split(filename, ".")[0], "_") if words[0] == "input" || words[0] == "output" { byte_stream := this.InitByteStream(filepath.Join(this.bin_dirpath, filename)) chunk := new(Chunk) chunk.Init(filename, byte_stream) if chunk.ChunkType() == INPUT_DPU_HOST { this.input_dpu_host = append(this.input_dpu_host, chunk) } else if chunk.ChunkType() == OUTPUT_DPU_HOST { this.output_dpu_host = append(this.output_dpu_host, chunk) } else if chunk.ChunkType() == INPUT_DPU_MRAM_HEAP_POINTER_NAME { this.input_dpu_mram_heap_pointer_name = append(this.input_dpu_mram_heap_pointer_name, chunk) } else if chunk.ChunkType() == OUTPUT_DPU_MRAM_HEAP_POINTER_NAME { this.output_dpu_mram_heap_pointer_name = append(this.output_dpu_mram_heap_pointer_name, chunk) } else { chunk_type_err := errors.New("chunk type is not valid") panic(chunk_type_err) } } } } func (this *Host) InitByteStream(path string) *encoding.ByteStream { file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, line := range lines { value, err := strconv.Atoi(line) if err != nil { panic(err) } byte_stream.Append(uint8(value)) } return byte_stream } func (this *Host) Fini() { } func (this *Host) ConnectChannels(channels []*channel.Channel) { this.channels = channels } func (this *Host) NumExecutions() int { return this.num_executions } func (this *Host) Dpus() []*dpu.Dpu { dpus := make([]*dpu.Dpu, 0) for _, channel_ := range this.channels { dpus = append(dpus, channel_.Dpus()...) } return dpus } func (this *Host) IsZombie() bool { dpus := this.Dpus() for _, dpu_ := range dpus { if !dpu_.IsZombie() { return false } } return true } func (this *Host) Load() { this.DmaTransferToAtomic() this.DmaTransferToIram() this.DmaTransferToWram() this.DmaTransferToMram() } func (this *Host) Schedule(execution int) { // TODO(bongjoon.hyun@gmail.com): fix this if this.benchmark == "TRNS" { this.Load() } this.ChannelTransferInputDpuHost(execution) this.ChannelTransferInputDpuMramHeapPointerName(execution) } func (this *Host) Check(execution int) { this.ChannelTransferOutputDpuHost(execution) this.ChannelTransferOutputDpuMramHeapPointerName(execution) } func (this *Host) Launch() { config_loader := new(misc.ConfigLoader) config_loader.Init() dpus := this.Dpus() for _, dpu_ := range dpus { threads := dpu_.Threads() for _, thread := range threads { bootstrap := config_loader.IramOffset() thread.RegFile().WritePcReg(bootstrap) } dpu_.Boot() } } func (this *Host) DmaTransferToAtomic() { dpus := this.Dpus() thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) for _, dpu_ := range dpus { dma_transfer_to_atomic_job := new(DmaTransferToAtomicJob) dma_transfer_to_atomic_job.Init(this.atomic, dpu_) thread_pool.Enque(dma_transfer_to_atomic_job) } thread_pool.Start() } func (this *Host) DmaTransferToIram() { dpus := this.Dpus() thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) for _, dpu_ := range dpus { dma_transfer_to_iram_job := new(DmaTransferToIramJob) dma_transfer_to_iram_job.Init(this.iram, dpu_) thread_pool.Enque(dma_transfer_to_iram_job) } thread_pool.Start() } func (this *Host) DmaTransferToWram() { dpus := this.Dpus() thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) for _, dpu_ := range dpus { dma_transfer_to_wram_job := new(DmaTransferToWramJob) dma_transfer_to_wram_job.Init(this.wram, dpu_) thread_pool.Enque(dma_transfer_to_wram_job) } thread_pool.Start() } func (this *Host) DmaTransferToMram() { dpus := this.Dpus() thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) for _, dpu_ := range dpus { dma_transfer_to_mram_job := new(DmaTransferToMramJob) dma_transfer_to_mram_job.Init(this.mram, dpu_) thread_pool.Enque(dma_transfer_to_mram_job) } thread_pool.Start() } func (this *Host) ChannelTransferInputDpuHost(execution int) { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) pointers := this.FindInputDpuHostPointers(execution) for pointer, _ := range pointers { if _, found := this.addresses[pointer]; !found { err := errors.New("pointer is not found") panic(err) } address := this.addresses[pointer] for _, channel_ := range this.channels { channel_id := channel_.ChannelId() ranks := channel_.Ranks() for _, rank_ := range ranks { rank_id := rank_.RankId() dpus := rank_.Dpus() for i := 0; i < 8; i++ { dpu_ids := make([]int, 0) byte_streams := make([]*encoding.ByteStream, 0) for _, dpu_ := range dpus { dpu_id := dpu_.DpuId() unique_dpu_id := channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + rank_id*this.num_dpus_per_rank + dpu_id if dpu_id%8 == i { chunk := this.FindInputDpuHostChunk(pointer, execution, unique_dpu_id) dpu_ids = append(dpu_ids, dpu_id) byte_streams = append(byte_streams, chunk.ByteStream()) } } if len(byte_streams) != 0 && byte_streams[0].Size() != 0 { channel_message := new(channel.ChannelMessage) channel_message.InitWrite( channel_.ChannelId(), rank_.RankId(), dpu_ids, address, byte_streams[0].Size(), byte_streams, ) channel_transfer_write_job := new(ChannelTransferWriteJob) channel_transfer_write_job.Init(channel_message, channel_) thread_pool.Enque(channel_transfer_write_job) } } } } } thread_pool.Start() } func (this *Host) ChannelTransferOutputDpuHost(execution int) { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) pointers := this.FindOutputDpuHostPointers(execution) for pointer, _ := range pointers { if _, found := this.addresses[pointer]; !found { err := errors.New("pointer is not found") panic(err) } address := this.addresses[pointer] for _, channel_ := range this.channels { channel_id := channel_.ChannelId() ranks := channel_.Ranks() for _, rank_ := range ranks { rank_id := rank_.RankId() dpus := rank_.Dpus() for i := 0; i < 8; i++ { dpu_ids := make([]int, 0) byte_streams := make([]*encoding.ByteStream, 0) for _, dpu_ := range dpus { dpu_id := dpu_.DpuId() unique_dpu_id := channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + rank_id*this.num_dpus_per_rank + dpu_id if dpu_id%8 == i { chunk := this.FindOutputDpuHostChunk(pointer, execution, unique_dpu_id) dpu_ids = append(dpu_ids, dpu_id) byte_streams = append(byte_streams, chunk.ByteStream()) } } if len(byte_streams) != 0 && byte_streams[0].Size() != 0 { channel_message := new(channel.ChannelMessage) channel_message.InitRead( channel_.ChannelId(), rank_.RankId(), dpu_ids, address, byte_streams[0].Size(), ) channel_transfer_read_job := new(ChannelTransferReadJob) channel_transfer_read_job.Init(channel_message, byte_streams, channel_) thread_pool.Enque(channel_transfer_read_job) } } } } } thread_pool.Start() } func (this *Host) ChannelTransferInputDpuMramHeapPointerName(execution int) { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) if _, found := this.values["__sys_used_mram_end"]; !found { err := errors.New("__sys_used_mram_end is not found") panic(err) } sys_used_mram_end := this.values["__sys_used_mram_end"] offsets := this.FindInputDpuMramHeapPointerNameOffsets(execution) for offset, _ := range offsets { address := sys_used_mram_end + offset for _, channel_ := range this.channels { channel_id := channel_.ChannelId() ranks := channel_.Ranks() for _, rank_ := range ranks { rank_id := rank_.RankId() dpus := rank_.Dpus() for i := 0; i < 8; i++ { dpu_ids := make([]int, 0) byte_streams := make([]*encoding.ByteStream, 0) for _, dpu_ := range dpus { dpu_id := dpu_.DpuId() unique_dpu_id := channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + rank_id*this.num_dpus_per_rank + dpu_id if dpu_id%8 == i { chunk := this.FindInputDpuMramHeapPointerNameChunk( offset, execution, unique_dpu_id, ) dpu_ids = append(dpu_ids, dpu_id) byte_streams = append(byte_streams, chunk.ByteStream()) } } if len(byte_streams) != 0 && byte_streams[0].Size() != 0 { channel_message := new(channel.ChannelMessage) channel_message.InitWrite( channel_.ChannelId(), rank_.RankId(), dpu_ids, address, byte_streams[0].Size(), byte_streams, ) channel_transfer_write_job := new(ChannelTransferWriteJob) channel_transfer_write_job.Init(channel_message, channel_) thread_pool.Enque(channel_transfer_write_job) } } } } } thread_pool.Start() } func (this *Host) ChannelTransferOutputDpuMramHeapPointerName(execution int) { thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) if _, found := this.values["__sys_used_mram_end"]; !found { err := errors.New("__sys_used_mram_end is not found") panic(err) } sys_used_mram_end := this.values["__sys_used_mram_end"] offsets := this.FindOutputDpuMramHeapPointerNameOffsets(execution) for offset, _ := range offsets { address := sys_used_mram_end + offset for _, channel_ := range this.channels { channel_id := channel_.ChannelId() ranks := channel_.Ranks() for _, rank_ := range ranks { rank_id := rank_.RankId() dpus := rank_.Dpus() for i := 0; i < 8; i++ { dpu_ids := make([]int, 0) byte_streams := make([]*encoding.ByteStream, 0) for _, dpu_ := range dpus { dpu_id := dpu_.DpuId() unique_dpu_id := channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + rank_id*this.num_dpus_per_rank + dpu_id if dpu_id%8 == i { chunk := this.FindOutputDpuMramHeapPointerNameChunk( offset, execution, unique_dpu_id, ) dpu_ids = append(dpu_ids, dpu_id) byte_streams = append(byte_streams, chunk.ByteStream()) } } if len(byte_streams) != 0 && byte_streams[0].Size() != 0 { channel_message := new(channel.ChannelMessage) channel_message.InitRead( channel_.ChannelId(), rank_.RankId(), dpu_ids, address, byte_streams[0].Size(), ) channel_transfer_read_job := new(ChannelTransferReadJob) channel_transfer_read_job.Init(channel_message, byte_streams, channel_) thread_pool.Enque(channel_transfer_read_job) } } } } thread_pool.Start() } } func (this *Host) FindInputDpuHostPointers(execution int) map[string]bool { pointers := make(map[string]bool, 0) for _, chunk := range this.input_dpu_host { if chunk.Execution() == execution { pointers[chunk.Name()] = true } } return pointers } func (this *Host) FindOutputDpuHostPointers(execution int) map[string]bool { pointers := make(map[string]bool, 0) for _, chunk := range this.output_dpu_host { if chunk.Execution() == execution { pointers[chunk.Name()] = true } } return pointers } func (this *Host) FindInputDpuMramHeapPointerNameOffsets(execution int) map[int64]bool { offsets := make(map[int64]bool, 0) for _, chunk := range this.input_dpu_mram_heap_pointer_name { if chunk.Execution() == execution { offsets[chunk.Offset()] = true } } return offsets } func (this *Host) FindOutputDpuMramHeapPointerNameOffsets(execution int) map[int64]bool { offsets := make(map[int64]bool, 0) for _, chunk := range this.output_dpu_mram_heap_pointer_name { if chunk.Execution() == execution { offsets[chunk.Offset()] = true } } return offsets } func (this *Host) FindInputDpuHostChunk(pointer string, execution int, dpu_id int) *Chunk { for _, chunk := range this.input_dpu_host { if chunk.Name() == pointer && chunk.Execution() == execution && chunk.DpuId() == dpu_id { return chunk } } err := errors.New("chunk is not found") panic(err) } func (this *Host) FindOutputDpuHostChunk(pointer string, execution int, dpu_id int) *Chunk { for _, chunk := range this.output_dpu_host { if chunk.Name() == pointer && chunk.Execution() == execution && chunk.DpuId() == dpu_id { return chunk } } err := errors.New("chunk is not found") panic(err) } func (this *Host) FindInputDpuMramHeapPointerNameChunk( offset int64, execution int, dpu_id int, ) *Chunk { for _, chunk := range this.input_dpu_mram_heap_pointer_name { if chunk.Offset() == offset && chunk.Execution() == execution && chunk.DpuId() == dpu_id { return chunk } } err := errors.New("chunk is not found") panic(err) } func (this *Host) FindOutputDpuMramHeapPointerNameChunk( offset int64, execution int, dpu_id int, ) *Chunk { for _, chunk := range this.output_dpu_mram_heap_pointer_name { if chunk.Offset() == offset && chunk.Execution() == execution && chunk.DpuId() == dpu_id { return chunk } } err := errors.New("chunk is not found") panic(err) } func (this *Host) Cycle() { if _, found := this.addresses["__sys_end"]; !found { err := errors.New("__sys_end is not found") panic(err) } sys_end := this.addresses["__sys_end"] thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) dpus := this.Dpus() for _, dpu_ := range dpus { cycle_job := new(CycleJob) cycle_job.Init(sys_end, dpu_) thread_pool.Enque(cycle_job) } thread_pool.Start() } ================================================ FILE: golang/uPIMulator/src/simulator/rank/rank.go ================================================ package rank import ( "errors" "uPIMulator/src/abi/encoding" "uPIMulator/src/misc" "uPIMulator/src/simulator/dpu" ) type Rank struct { channel_id int rank_id int dpus []*dpu.Dpu } func (this *Rank) Init(channel_id int, rank_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpus = make([]*dpu.Dpu, 0) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) for i := 0; i < num_dpus_per_rank; i++ { dpu_ := new(dpu.Dpu) dpu_.Init(channel_id, rank_id, i, command_line_parser) this.dpus = append(this.dpus, dpu_) } } func (this *Rank) Fini() { for _, dpu_ := range this.dpus { dpu_.Fini() } } func (this *Rank) RankId() int { return this.rank_id } func (this *Rank) NumDpus() int { return len(this.dpus) } func (this *Rank) Dpus() []*dpu.Dpu { return this.dpus } func (this *Rank) Read(dpu_id int, address int64, size int64) *encoding.ByteStream { dpu_ := this.dpus[dpu_id] if dpu_.DpuId() != dpu_id { err := errors.New("DPU's DPU ID != DPU ID") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() if config_loader.WramOffset() <= address && address+size <= config_loader.WramOffset()+config_loader.WramSize() { return dpu_.Dma().TransferFromWram(address, size) } else if config_loader.MramOffset() <= address && address+size <= config_loader.MramOffset()+config_loader.MramSize() { return dpu_.Dma().TransferFromMram(address, size) } else { err := errors.New("address does not fall under WRAM nor MRAM region") panic(err) } } func (this *Rank) Write(dpu_id int, address int64, byte_stream *encoding.ByteStream) { dpu_ := this.dpus[dpu_id] if dpu_.DpuId() != dpu_id { err := errors.New("DPU's DPU ID != DPU ID") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() if config_loader.WramOffset() <= address && address+byte_stream.Size() <= config_loader.WramOffset()+config_loader.WramSize() { dpu_.Dma().TransferToWram(address, byte_stream) } else if config_loader.MramOffset() <= address && address+byte_stream.Size() <= config_loader.MramOffset()+config_loader.MramSize() { dpu_.Dma().TransferToMram(address, byte_stream) } else { err := errors.New("address does not fall under WRAM nor MRAM region") panic(err) } } ================================================ FILE: golang/uPIMulator/src/simulator/simulator.go ================================================ package simulator import ( "fmt" "path/filepath" "uPIMulator/src/core" "uPIMulator/src/misc" "uPIMulator/src/simulator/channel" "uPIMulator/src/simulator/host" ) type Simulator struct { host *host.Host channels []*channel.Channel bin_dirpath string num_simulation_threads int execution int verbose int } func (this *Simulator) Init(command_line_parser *misc.CommandLineParser) { this.host = new(host.Host) this.host.Init(command_line_parser) this.verbose = int(command_line_parser.IntParameter("verbose")) num_channels := int(command_line_parser.IntParameter("num_channels")) this.channels = make([]*channel.Channel, 0) for i := 0; i < num_channels; i++ { channel_ := new(channel.Channel) channel_.Init(i, command_line_parser) this.channels = append(this.channels, channel_) } this.host.ConnectChannels(this.channels) this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.num_simulation_threads = int(command_line_parser.IntParameter("num_simulation_threads")) this.execution = 0 this.host.Load() this.host.Schedule(this.execution) this.host.Launch() } func (this *Simulator) Fini() { this.host.Fini() for _, channel_ := range this.channels { channel_.Fini() } } func (this *Simulator) IsFinished() bool { return this.execution == this.host.NumExecutions() } func (this *Simulator) Cycle() { this.host.Cycle() thread_pool := new(core.ThreadPool) thread_pool.Init(this.num_simulation_threads) dpus := this.host.Dpus() for _, dpu_ := range dpus { cycle_job := new(CycleJob) cycle_job.Init(dpu_) thread_pool.Enque(cycle_job) } thread_pool.Start() if this.host.IsZombie() { fmt.Printf("execution (%d) is finished...\n", this.execution) this.host.Check(this.execution) this.execution++ if !this.IsFinished() { this.host.Schedule(this.execution) this.host.Launch() } } if this.verbose >= 1 { fmt.Println("system is cycling...") } } func (this *Simulator) Dump() { file_dumper := new(misc.FileDumper) file_dumper.Init(filepath.Join(this.bin_dirpath, "log.txt")) lines := make([]string, 0) dpus := this.host.Dpus() for _, dpu_ := range dpus { lines = append(lines, dpu_.StatFactory().ToLines()...) lines = append(lines, dpu_.ThreadScheduler().StatFactory().ToLines()...) lines = append(lines, dpu_.Logic().StatFactory().ToLines()...) lines = append(lines, dpu_.Logic().CycleRule().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().MemoryScheduler().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().RowBuffer().StatFactory().ToLines()...) } file_dumper.WriteLines(lines) } ================================================ FILE: golang_vm/README.md ================================================ # ⚙️ Install and Build ## Usage Mode uPIMulator currently operates in an execution-driven mode. The typical workflow involves the following steps: 1. **Compilation and Linking:** Compile and link your application code to generate device-side binary files. 2. **Host-Side Interpretation:** The host-side virtual machine interprets the host code, orchestrating interactions with the device-side cycle-level simulator. 3. **Simulation and Results:** The simulator executes the device-side binary and provides detailed cycle-level simulation results. We are actively exploring new usage modes and features to enhance uPIMulator's flexibility. ## Prerequisites - Go Compiler: uPIMulator requires Go version 1.21.5 or higher. You can download and install Go from the [official website](https://go.dev/doc/install). - Docker: Please ensure that Docker is installed on your system. - Docker Group Membership: Your Ubuntu user account needs to be a member of the docker group. - Tested Environment: uPIMulator has been thoroughly tested on Ubuntu 18.04 with an Intel CPU. While we strive for compatibility across different environments, optimal performance and functionality are ensured within the tested setup. If you encounter issues in unsupported environments, please report them via GitHub Issues. We appreciate your feedback as we continue to improve and expand uPIMulator's compatibility. ## Install ```bash cd /path/to/uPIMulator/script python3 build.py ``` ### Verification Upon successfully installing and building, the uPIMulator executable will be located in the `/path/to/uPIMulator/build` directory. Please ensure that you replace `/path/to/uPIMulator` with the actual path where you cloned or downloaded the uPIMulator repository. If you encounter any difficulties during the installation or build process, or if the executable is not found in the expected location, please refer to the troubleshooting section of the documentation or feel free to open an issue on our GitHub repository. # 🧪 Running the PrIM Benchmark Suite ## Validation with PrIM Benchmark Suite uPIMulator's accuracy and functionality have been validated using PrIM, an open-source UPMEM-PIM benchmark suite comprising 16 data-intensive workloads across diverse application domains (linear algebra, graph processing, neural networks, etc.). Among the 16 benchmarks, uPIMulator successfully simulates 13 without modifications. The remaining three (BFS, SpMV, NW) presented challenges due to minor bugs or their reliance on undisclosed UPMEM SDK functions, hindering their simulation and debugging within uPIMulator. Consequently, these three benchmarks are currently excluded from the exemplar benchmarks provided in this repository. We are actively working to address these limitations and expand uPIMulator's compatibility with the full PrIM benchmark suite in future releases. ## Running a Simulation We'll use the VA (vector addition) benchmark to illustrate the simulation process. Please note that the initial simulation might take approximately 30 minutes. ### Execution To initiate a simulation, provide the following: - **Benchmark name:** Specify the desired benchmark (e.g., `VA`). - **Number of tasklets:** Define the number of tasklets to be utilized. - **Output directory path:** Indicate the absolute path to the directory where you want to store binary files, log files, and other simulation artifacts. You can further customize the simulation by utilizing command-line options to adjust various parameters. ### Simulation Output Detailed simulation results will be written to `/path/to/bin/log.txt`. > **Note:** Be sure to replace `/path/to/bin` with the absolute path to your chosen output directory. ### Important Notes - **Create Output Directory:** Prior to running the simulation, manually create an empty directory at the specified `bin_dirpath` before running the simulation. - **Absolute Paths:** Always provide absolute paths for both `root_dirpath` (the repository's root directory) and `bin_dirpath`. ```bash cd /path/to/uPIMulator rm -rf bin mkdir bin ./build/uPIMulator --root_dirpath /path/to/uPIMulator --bin_dirpath /path/to/uPIMulator/bin --benchmark VA --num_channels 1 --num_ranks_per_channel 1 --num_dpus_per_rank 1 --num_tasklets 16 --data_prep_params 1024 ``` You can experiment with different benchmarks and configurations to explore uPIMulator's capabilities. # 🗒️ List of Parameters and Logs ## Configuration and Output The uPIMulator framework offers flexibility through command-line arguments and generates a log.txt file to present comprehensive simulation results. This documentation provides detailed explanations for each parameter and the structure of the log output, aiding in understanding and interpreting the simulation data. ## 🪂 Parameters ### Parameter Types uPIMulator utilizes two distinct parameter categories: - **Command-Line Parameters:** The `CommandLineParser` struct processes command-line arguments, configuring both the host-side virtual machine and the device-side UPMEM-PIM simulator before simulation commences. These parameters directly influence the simulation setup and execution. - **Configuration Parameters:** The `ConfigLoader` struct manages additional parameters that are less likely to affect the simulation results directly. These may include settings like IRAM address offsets or MRAM size, primarily influencing the simulated environment's configuration. | Command Line Arguments | Meaning | | --- | --- | | verbose | Runtime simulation status monitoring level (0: no monitoring, 1: restricted monitoring, 2: full monitoring) | | benchmark | Benchmark name | | num_channels | Number of PIM memory channels | | num_ranks_per_channel | Number of ranks per PIM memory channel | | num_dpus_per_rank | Number of DPUs per PIM memory rank | | num_vm_channels | Number of conventional memory channels attached to the host | | num_vm_ranks_per_channel | Number of ranks per conventional memory channel attached to the host | | num_vm_banks_per_rank | Number of DRAM banks per conventional memory rank attached to the host | | num_tasklets | Number of tasklets per DPU when running the benchmark | | data_prep_params | Value that configures the input size of the benchmark | | root_dirpath | Absolute path to the root directory of uPIMulator | | bin_dirpath | Absolute path to the bin directory where binary files and log files are dumped | | logic_frequency | DPU logic frequency in MHz | | memory_frequency | Operating frequency of PIM and conventional memory | | num_pipeline_stages | Number of DPU logic pipeline stages | | num_revolver_scheduling_cycles | Number of DPU logic revolver scheduling cycles in DPU's logic operating frequency | | wordline_size | Row buffer size per single DPU's MRAM and conventional DRAM bank in bytes | | min_access_granularity | Minimum access granularity in bytes of DPU's MRAM and conventional DRAM's bank | | t_rcd | t_RCD timing parameter of DPU's MRAM and conventional DRAM's bank in cycles in memory operating frequency | | t_ras | t_RAS timing parameter of DPU's MRAM and conventional DRAM's bank in cycles in memory operating frequency | | t_rp | t_RP timing parameter of DPU's MRAM and conventional DRAM's bank in cycles in memory operating frequency | | t_cl | t_CL timing parameter of DPU's MRAM and conventional DRAM's bank in cycles in memory operating frequency | | t_bl | t_BL timing parameter of DPU's MRAM and conventional DRAM's bank in cycles in memory operating frequency | | ConfigLoader Parameters | Meaning | | --- | --- | | AddressWidth | Bit width of all addresses (e.g., 32-bit machine or 64-bit machine) | | AtomicDataWidth | DPU's atomic region's bit width of all data | | AtomicOffset | Offset address of DPU's atomic region in DPU's physical address space | | AtomicSize | Size in bytes of DPU's atomic region | | IramDataWidth | DPU's IRAM's bit width of all data | | IramOffset | Offset address of DPU's IRAM in DPU's physical address space | | IramSize | Size in bytes of DPU's IRAM | | WramDataWidth | DPU's WRAM's bit width of all data | | WramOffset | Offset address of DPU's WRAM in DPU's physical address space | | WramSize | Size in bytes of DPU's WRAM | | MramDataWidth | DPU's MRAM's bit width of all data | | MramOffset | Offset address of DPU's MRAM in DPU's physical address space | | MramSize | Size in bytes of DPU's MRAM | | StackSize | A single DPU's stack size in bytes for each tasklet | | HeapSize | A single DPU's heap size in bytes | | NumGpRegisters | Number of general-purpose registers of a single DPU's each tasklet | | MaxNumTasklets | Max number of tasklets per each DPU | | VmBankOffset | Offset address of each bank of the virtual machine interpreting host-side benchmark code | | VmBankSize | Size in bytes of the virtual machine's each bank | | VmBg0 | Bit location of the first bank group bit for the virtual machine's DRAM address mapping | | VmBg1 | Bit location of the second bank group bit for the virtual machine's DRAM address mapping | | VmBank | Bit locations of the bank bits for the virtual machine's DRAM address mapping | | VmMemorySize | Initial memory size of the virtual machine | | GarbageCollectionThreshold | Number of bytecode executed before starting garbage collection in the virtual machine | ## 🪵 Logs ## Simulation Logging - **Log Storage and Output:** uPIMulator temporarily stores simulation logs within the `StatFactory` struct. Upon completion, these logs are written to a file named `log.txt` located in the designated `bin` directory. - **Custom Log Monitoring:** To track additional simulation behaviors, you can extend the `StatFactory` struct to include new log entries. Ensure that these new entries are incorporated into the `Dump` function within the `System` struct to facilitate their inclusion in the final log output. | Logs | Meaning | | --- | --- | | ThreadScheduler[X_Y_Z]_breakdown_etc | Number of DPU logic cycles of the DPU not being able to issue an instruction due to revolver pipeline in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | ThreadScheduler[X_Y_Z]_breakdown_run | Number of DPU logic cycles of the DPU being able to issue an instruction in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | ThreadScheduler[X_Y_Z]_breakdown_dma | Number of DPU logic cycles of the DPU not being able to issue an instruction due to data is not ready from MRAM in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | Logic[X_Y_Z]_backpressure | Number of DPU logic cycles of the DPU not being able to issue an instruction due to register file conflicts in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | Logic[X_Y_Z]_active_tasklets_N | Number of DPU logic cycles when number of N tasklets are active in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | Logic[X_Y_Z]_logic_cycle | Number of DPU logic cycles elapsed during PIM kernel execution in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | Logic[X_Y_Z]_num_instructions | Number of instructions executed by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | CycleRule[X_Y_Z]_cycle_rule | Total number of DPU logic cycles resolving register file conflicts for all threads in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | MemoryController[X_Y_Z]_memory_cycle | Number of MRAM memory cycles ticked in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | MemoryScheduler[X_Y_Z]_num_fr | Number of reordered memory commands thanks to FR-FCFS memory scheduling policy in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | MemoryScheduler[X_Y_Z]_num_fcfs | Number of non-reordered memory commands in the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_num_activations | Number of ACTIVATION memory commands received by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_num_precharges | Number of PRECHARGE memory commands received by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_num_reads | Number of READ memory commands received by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_num_writes | Number of WRITE memory commands received by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_read_bytes | Total number of bytes read by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | RowBuffer[X_Y_Z]_write_bytes | Total number of bytes written by the DPU with channel ID of X, rank ID of Y, and DPU ID of Z | | VmBank[X_Y_Z]_vm_memory_cycle | Number of host-side conventional DRAM memory cycles ticked by the DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | MemoryScheduler_num_fr | Number of reordered memory commands thanks to FR-FCFS memory scheduling policy in the host-attached memory controller in the virtual machine | | MemoryScheduler_num_fcfs | Number of non-reordered memory commands in the host-attached memory controller in the virtual machine | | VmRowBuffer[X_Y_Z]_num_activations | Number of ACTIVATION memory commands received by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | VmRowBuffer[X_Y_Z]_num_precharges | Number of PRECHARGE memory commands received by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | VmRowBuffer[X_Y_Z]_num_reads | Number of READ memory commands received by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | VmRowBuffer[X_Y_Z]_num_writes | Number of WRITE memory commands received by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | VmRowBuffer[X_Y_Z]_read_bytes | Total number of bytes read by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | | VmRowBuffer[X_Y_Z]_write_bytes | Total number of bytes written by the virtual machine's DRAM bank with channel ID of X, rank ID of Y, and bank ID of Z | # 🪑 Benchmark Addition ## Adding Custom Benchmarks In addition to the provided PrIM benchmarks, uPIMulator allows you to integrate your own benchmarks, especially if you have access to UPMEM-PIM hardware and your code runs successfully on the actual device. To incorporate your benchmark, you'll need to adapt your codebase to a format that uPIMulator's virtual machine can interpret. Detailed guidance on this process can be found in the **"Interpretable C Grammar"** section within this documentation. To add a custom benchmark beyond the existing PrIM suite, adhere to the following guidelines: 1. **Benchmark Location:** Place your new benchmark within the `benchmark` directory. 2. **UPMEM-C Language:** The benchmark code must be written in UPMEM-C, a modified C language specifically designed for UPMEM-PIM programming, similar to CUDA for NVIDIA GPUs. Refer to the UPMEM SDK documentation for comprehensive instructions on the UPMEM programming model. 3. **File Structure and Naming:** Maintain the same file hierarchy and naming conventions used in the PrIM benchmarks (e.g., `VA/host/app.c` and `VA/dpu/task.c`). 4. **CMakeLists.txt:** Include a `CMakeLists.txt` file within your benchmark's directory hierarchy, mirroring the structure used in the PrIM examples. This is essential as uPIMulator's interpreter and linker automatically detect and compile benchmarks using these `CMakeLists.txt` files. > **Note:** These structural requirements ensure seamless integration with uPIMulator's build and execution processes. # 🏊 Delving into the Host-Side Virtual Machine ## Host-Side Virtual Machine and Interpretable C Grammar The host-side virtual machine interprets host-side code written in a subset of C, eliminating the need for manual input/output data preparation. ## Interpretable C Grammar uPIMulator's interpreter, responsible for generating bytecode for the virtual machine, consists of three components: the lexer, the parser, and the code generator. ### Supported Data Types - `char` - `short` - `int` - `long` (64-bit integers in the uPIMulator's virtual machine) ### Limitations and Exceptions While the interpreter strives to handle standard C grammar, certain features are currently unsupported due to the virtual machine's constraints: - **Comments:** Any kind of comments (`//` or `/* */`) are not allowed. - **Header Files:** Including header files will be ignored. - **Linking:** The host-side virtual machine does not support linking. All code must reside in a single file named `app.c` within the benchmark directory. - **`#define` Directives:** - `#define NUM_DPUS`, `#define NUM_TASKLETS`, and `#define DATA_PREP_PARAMS` will be replaced with their corresponding command-line arguments (i.e., `--num_dpus`, `--num_tasklets`, `--data_prep_params`). - Other `#define` directives will have their right-hand side (rvalue) evaluated and assigned. The rvalue must be a single number. - **Macro Functions:** Macro functions are not permitted. - **Conditional Compilation:** Constructs like `#if`, `#ifdef`, etc., are not supported. - **Data Types and Keywords:** - `bool`, `static`, `unsigned`, `union`, `enum`, `const`, and `typedef` keywords are not supported. - **Struct Initialization:** - Struct variables must be initialized using `malloc` (e.g., `struct foo_t bar = malloc(sizeof(struct foo_t));`). - `sizeof` expressions cannot infer variable types by name. - Direct struct initialization (e.g., `struct foo_t bar = {1, 2};`) is not supported. - **Expressions and Operators:** - Assignment statements (`a = 2`) and increment/decrement operators (`i++`, `--j`) do not evaluate to expressions. - The virtual machine evaluates all expressions, even in short-circuit logical operations (e.g., both `expr_a` and `expr_b` will be evaluated in `expr_a || expr_b`, even if `expr_a` is true). - **Other Restrictions:** - Array declarations (`int a[10];`) and `switch-case` statements are not allowed. - Nested pointers (`int** p;`) and pointer arithmetic (`p + 1`) are not supported. - Curly braces are mandatory for control flow structures (e.g., `if (foo) bar();` is invalid). - Type casting (e.g., `(int *) p`) is not permitted. - The `main` function should not have any arguments (`int main() {...}`). - Standard library calls, except for `malloc` and `free`, are not supported (e.g., `printf` cannot be used). - Only the following UPMEM SDK library functions are supported: `dpu_alloc`, `dpu_load`, `dpu_prepare`, `dpu_push_xfer`, `dpu_copy_to`, `dpu_copy_from`, `dpu_launch`, and `dpu_free`. - `float` and `double` types are not supported. Please adhere to these guidelines when writing host-side code for uPIMulator. We are continuously working to expand the supported C grammar and features in future releases. ## 🏗️ Virtual Machine Overview ### Host-Side Interpreter and Virtual Machine Architecture uPIMulator employs a streamlined host-side interpreter and virtual machine to facilitate the interpretation of C code. While this approach offers benefits in terms of simplicity and ease of use, it also entails certain limitations, as outlined in the **"Interpretable C Grammar"** section above. Consequently, some modifications to your host-side C code may be necessary to ensure compatibility with uPIMulator's interpreter and virtual machine. ### Interpreter The interpreter follows a three-stage process to generate bytecode, which is subsequently executed by the virtual machine: 1. **Lexical Analysis (Lexer):** The lexer breaks down the C source code into a stream of tokens. 2. **Syntax Analysis (Parser):** The parser constructs an Abstract Syntax Tree (AST) from the token stream, representing the code's structure. 3. **Code Generation (Codegen):** The codegen translates the AST into bytecode instructions for the virtual machine. > **Note:** The interpreter currently lacks type checking capabilities. > To ensure type safety, we strongly recommend utilizing a C compiler (such as GCC) to identify any compilation errors before attempting simulation with uPIMulator. ### Virtual Machine The virtual machine executes the generated bytecode sequentially, similar to other virtual machines like the Java Virtual Machine (JVM) or Python Virtual Machine. It operates using a stack-based architecture, where data is manipulated on the stack rather than in registers. A basic mark-and-sweep garbage collector is implemented within the virtual machine. We are actively exploring enhancements to the garbage collection and memory management mechanisms to further optimize performance. We are committed to ongoing development and improvement of the interpreter and virtual machine to provide a more robust and efficient simulation environment. ### 💿 Bytecode #### Bytecode and Data Types - **Bytecode:** Bytecode serves as the fundamental instruction set for the virtual machine, representing the compiled form of the host-side C code. - **Data Types:** Within the virtual machine environment, the long data type is represented as an 8-byte integer. | Bytecode | Meaning | Arg1 | Arg2 | Str1 | Str2 | | --- | --- | --- | --- | --- | --- | | NEW_SCOPE | Creates a new scope that stores symbols for the new block statement | | | | | | DELETE_SCOPE | Deletes the last scope when exiting a block statement | | | | | | PUSH_CHAR | Push a char type or char type pointer object onto the stack | Value | | | | | PUSH_SHORT | Push a short type or short type pointer object onto the stack | Value | | | | | PUSH_INT | Push an int type or int type pointer object onto the stack | Value | | | | | PUSH_LONG | Push a long type or long type pointer object onto the stack | Value | | | | | PUSH_STRING | Push a string type or string type pointer object onto the stack | | | Characters | | | POP | Pop an object from the stack | | | | | | BEGIN_STRUCT | Start registering a custom data structure (i.e., C struct), aka skeleton, to the virtual machine's registry | | | struct type name | | | APPEND_VOID | Append a void type or void type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field name | | | APPEND_CHAR | Append a char type or char type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field name | | | APPEND_SHORT | Append a short type or short type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field name | | | APPEND_INT | Append an int type or int type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field name | | | APPEND_LONG | Append a long type or long type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field name | | | APPEND_STRUCT | Append a struct type or struct type pointer field to the recently registered skeleton | Number of stars (i.e., *) | | Field's struct type name | Field name | | END_STRUCT | End registering a skeleton to the virtual machine's registry | | | | | | NEW_GLOBAL_VOID | Creates a void type or void type pointer global symbol in the global scope | Number of stars (i.e., *) | | Identifier name | | | NEW_GLOBAL_CHAR | Creates a char type or char type pointer global symbol in the global scope | Number of stars (i.e., *) | | Identifier name | | | NEW_GLOBAL_SHORT | Creates a short type or short type pointer global symbol in the global scope | Number of stars (i.e., *) | | Identifier name | | | NEW_GLOBAL_INT | Creates an int type or int type pointer global symbol in the global scope | Number of stars (i.e., *) | | Identifier name | | | NEW_GLOBAL_LONG | Creates a long type or long type pointer global symbol in the global scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_VOID | Creates a void type or void type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_CHAR | Creates a char type or char type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_SHORT | Creates a short type or short type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_INT | Creates an int type or int type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_LONG | Creates a long type or long type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | Identifier name | | | NEW_FAST_STRUCT | Creates a struct type or struct type pointer fast (i.e., local) symbol in the fast scope | Number of stars (i.e., *) | | struct type name | Identifier name | | NEW_ARG_VOID | Creates a void type or void type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | Identifier name | | | NEW_ARG_CHAR | Creates a char type or char type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | Identifier name | | | NEW_ARG_SHORT | Creates a short type or short type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | Identifier name | | | NEW_ARG_INT | Creates an int type or int type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | Identifier name | | | NEW_ARG_LONG | Creates a long type or long type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | Identifier name | | | NEW_ARG_STRUCT | Creates a struct type or struct type pointer argument symbol in the argument scope upon function call | Number of stars (i.e., *) | | struct type name | Identifier name | | NEW_RETURN_VOID | Creates a void type or void type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | NEW_RETURN_CHAR | Creates a char type or char type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | NEW_RETURN_SHORT | Creates a short type or short type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | NEW_RETURN_INT | Creates a int type or int type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | NEW_RETURN_LONG | Creates a long type or long type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | NEW_RETURN_STRUCT | Creates a struct type or struct type pointer in the return stack upon function return | Number of stars (i.e., *) | | | | | SIZE_OF_VOID | Push the size of the void type or void type pointer on the stack | Number of stars (i.e., *) | | | | | SIZE_OF_CHAR | Push the size of the char type or char type pointer on the stack | Number of stars (i.e., *) | | | | | SIZE_OF_SHORT | Push the size of the short type or short type pointer on the stack | Number of stars (i.e., *) | | | | | SIZE_OF_INT | Push the size of the int type or int type pointer on the stack | Number of stars (i.e., *) | | | | | SIZE_OF_LONG | Push the size of the long type or long type pointer on the stack | Number of stars (i.e., *) | | | | | SIZE_OF_STRUCT | Push the size of the struct type or struct type pointer on the stack | Number of stars (i.e., *) | | struct type name | | | GET_IDENTIFIER | Push the object of the symbol from global or fast scopes with identifier name on the stack | | | Identifier name | | | GET_ARG_IDENTIFIER | Push the object of the symbol from argument scope with identifier name on the stack | | | Identifier name | | | GET_SUBSCRIPT | Push an object of an array item on the stack | | | | | | GET_ACCESS | Push an object of a skeleton's field on the stack | | | | | | GET_REFERENCE | Push an object of a pointer to skeleton's field on the stack | | | | | | GET_ADDRESS | Push an address of an object on the stack | | | | | | GET_VALUE | Push reference of an object on the stack | | | | | | ALLOC | Allocates an object when calling C malloc function | | | | | | FREE | Deallocates an object when calling C free function | | | | | | ASSERT | Assert if the top of stack item is zero | | | | | | ADD | Add two stack items on the top and push the result on the stack | | | | | | SUB | Subtract two stack items on the top and push the result on the stack | | | | | | MUL | Multiply two stack items on the top and push the result on the stack | | | | | | DIV | Divide two stack items on the top and push the result on the stack | | | | | | MOD | Conduct a modular operation for two stack items on the top and push the result on the stack | | | | | | LSHIFT | Conduct a shift-to-the-left operation for two stack items on the top and push the result on the stack | | | | | | RSHIFT | Conduct a shift-to-the-right operation for two stack items on the top and push the result on the stack | | | | | | NEGATE | Conduct a logical not operation for top of the stack item on the top and push the result on the stack | | | | | | TILDE | Conduct a bitwise not operation for top of the stack item on the top and push the result on the stack | | | | | | SQRT | Conduct a square root operation for top of the stack item on the top and push the result on the stack | | | | | | BITWISE_AND | Conduct a bitwise and operation for two stack items on the top and push the result on the stack | | | | | | BITWISE_XOR | Conduct a bitwise xor operation for two stack items on the top and push the result on the stack | | | | | | BITWISE_OR | Conduct a bitwise or operation for two stack items on the top and push the result on the stack | | | | | | LOGICAL_AND | Conduct a logical and operation for two stack items on the top and push the result on the stack | | | | | | LOGICAL_OR | Conduct a logical xor operation for two stack items on the top and push the result on the stack | | | | | | LOGICAL_NOT | Conduct a logical not operation for top of the stack item on the top and push the result on the stack | | | | | | EQ | Conduct an equality operation for two stack items on the top and push the result on the stack | | | | | | NOT_EQ | Conduct an not-equality operation for two stack items on the top and push the result on the stack | | | | | | CONDITIONAL | Conduct a conditional operation for three stack items on the top and push the result on the stack | | | | | | ASSIGN | Assign the value of object of the top of the stack to the object in the second to the top of the stack | | | | | | ASSIGN_STAR | Conduct a multiplication operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_DIV | Conduct a division operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_MOD | Conduct a modular operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_ADD | Conduct an addition operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_SUB | Conduct a Subtraction operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_LSHIFT | Conduct a shift-to-the-left operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_RSHIFT | Conduct a shift-to-the-right operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_BITWISE_AND | Conduct a bitwise and operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_BITWISE_XOR | Conduct a bitwise xor operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_BITWISE_OR | Conduct a bitwise or operation for two stack items on the top and assign the value to the object in the second top of the stack | | | | | | ASSIGN_PLUS_PLUS | Increment by one of the stack item on the top and assign the value to the object | | | | | | ASSIGN_MINUS_MINUS | Decrement by one of the stack item on the top and assign the value to the object | | | | | | ASSIGN_RETURN | Assign the value of the object in the top of the stack to the stack item on the top of the return stack | | | | | | JUMP | Jump to a label by changing the program counter (PC) | | | label name | | | JUMP_IF_ZERO | Jump to a label if the value on the top of the stack is zero by changing the program counter (PC) | | | | | | JUMP_IF_NONZERO | Jump to a label if the value on the top of the stack is non-zero by changing the program counter (PC) | | | | | | CALL | Call a function by changing the program counter (PC) and pass function arguments | | | | | | RETURN | Return from a function and pass the value from return stack to the stack if exists | | | | | | NOP | Do nothing | | | | | | DPU_ALLOC | Allocate a single DPU | DPU ID | | | | | DPU_LOAD | Load PIM kernel to the allocated DPUs | DPU ID | | Benchmark name | | | DPU_PREPARE | Prepare for a data transfer between the virtual machine and DPUs | | | | | | DPU_TRANSFER | Transfer the prepared data between the virtual machine and DPUs | | | | | | DPU_LAUNCH | Launch the loaded PIM kernel to the allocated DPUs | | | | | | DPU_FREE | Deallocate DPUs | | | | | ### 🧠 Memory Management in uPIMulator's Virtual Machine uPIMulator's virtual machine employs a dynamic memory management system to handle objects, arenas, and data transfers within the simulated environment. #### Key Components - **Object:** The fundamental unit of memory, representing a typed data entity with an address and size. - **Arena:** Manages the allocation and deallocation of objects using a pool structure. - **Pool:** Maintains a list of objects and provides allocation/deallocation functionalities. Currently employs a best-fit algorithm for allocation, which we plan to optimize for improved efficiency. - **Arena:** Provides wrapper functions for `Pool` operations, such as `NewInt` for allocating and initializing integer objects. - **Memory:** A byte stream storing the actual data for all objects, with `Read` and `Write` APIs for data access. - **PC (Program Counter):** Tracks the current execution point within the bytecode for each encountered label. - **Stack and Return Stack:** - **Stack:** Maintains a stack of `StackItem` structs, each encapsulating a `TypeVariable` (specifying the data type), address, and size. - **Return Stack:** Similar to the stack, but specifically used for storing return values from function calls. - **Scope:** - **Scope Chain:** Manages a chain (FIFO queue) of `Scope` structs, each associating symbol names with their runtime objects. - **Scope Types:** - `global`: Holds globally defined symbols and those defined by `#define` macros. - `fast`: Stores locally defined symbols within block statements, forming a chain of fast scopes as new blocks are encountered. - `arg`: Contains symbols passed as arguments during function calls, transferred to the fast scope after the call. - **Type System:** A dynamic type system where each stack item's type is specified by a `TypeVariable`. Custom struct types are dynamically registered and tracked using `Skeleton` and `Registry` structs. - **Frame:** - **Frame Chain:** Manages a chain of `Frame` structs, each created upon jumping to a new label. - **Frame Structure:** Encapsulates a stack, return stack, scope chain, arguments scope, and PC for managing program execution context. - **DRAM:** Simulates the timing of host-side DRAM accesses. Employs a channel-rank-bank hierarchy and a FR-FCFS scheduling policy. Key components include: - `TransferCommand`: Encapsulates information for DMA transfers between host and device memory. - `MemoryController`: Translates `TransferCommand` into `MemoryCommand` sequences using `MemoryMapping` and `MemoryScheduler`. - `MemoryMapping`: Maps virtual machine addresses to physical DRAM locations (channel, rank, bank, bank address). - `MemoryScheduler`: Generates `MemoryCommand` (`ACTIVATE`, `READ`, `WRITE`, `PRECHARGE`) sequences and manages open rows. - `RowBuffer`: Models the timing behavior of a DRAM bank, including activation delays, read/write latencies, and precharge time. #### Cycle Function Calls The virtual machine invokes `Cycle` functions during data transfers between host and device memory or during PIM kernel execution. - **Memory Transfers:** Only the `Cycle` functions of the involved memories are called; DPU logic is not simulated. - **PIM Kernel Execution:** The PIM memory's `Cycle` function is called throughout the entire execution, encompassing both kernel computation and data transfers. Specific cycle counts (e.g., `Logic[X_Y_Z]_logic_cycle`, `VmBank[X_Y_Z]_vm_memory_cycle`, `MemoryController[X_Y_Z]_memory_cycle`) can be multiplied by their respective clock frequencies to estimate wall clock times. We are continuously refining and enhancing the memory management and simulation mechanisms within uPIMulator. Please refer to the documentation for more in-depth technical details and stay tuned for future updates! # 🏭 Delving into the Device-side UPMEM-PIM Simulator ## Device-Side UPMEM-PIM Simulator The device-side component of uPIMulator accurately models the behavior and timing characteristics of UPMEM-PIM hardware. This enables detailed cycle-level simulations of PIM-based computations and memory interactions, providing insights into performance and potential optimizations. ## 🏗️ UPMEM-PIM Simulator Overview ## Device-Side UPMEM-PIM Simulator The device-side UPMEM-PIM simulator exclusively supports execution-driven simulation, employing a producer-consumer model within its hardware components. ## Core Structure - **Initialization and Destruction:** All hardware components are initialized using an `Init` function and deconstructed using a `Fini` function. - **Communication:** Components interact via `Push` and `Pop` functions to send requests (e.g., `DmaCommand`, `MemoryCommand`) and receive responses, utilizing corresponding queue structures (e.g., `DmaCommandQ`, `MemoryCommandQ`). - **Cycle-Level Simulation:** Each component possesses a `Cycle` function defining its single-cycle behavior. Parent components invoke the `Cycle` functions of their child components (e.g., `MemoryController` calls `RowBuffer`'s `Cycle` function). ## Key Components ### Compiler The simulator's compiler utilizes a Docker container to compile benchmark code and the UPMEM SDK using `dpu-upmem-dpurte-clang`, generating assembly code for the linker. ### Linker The linker comprises three stages: 1. **Lexer:** Converts UPMEM assembly source code into a token stream. 2. **Parser:** Transforms the token stream into an Abstract Syntax Tree (AST). 3. **Logic:** Implements four algorithms guided by the linker script (`uPIMulator/sdk/misc/dpu.lds`) to determine memory assignments for code sections. - **Liveness Analysis (`LivenessAnalyzer`):** Analyzes the AST to establish linking relationships between benchmark and SDK library labels. - **Executable Generation (`MakeExecutable`):** Aggregates assembly files into a single `main.S` file, which is then lexed and parsed into a unified AST. - **Label Sizing (`LabelAssigner`):** Traverses the AST to calculate the size of each label. - **Address Assignment (`LinkerScript`):** Assigns addresses to labels based on their sizes and the linker script. - **Encoding:** Encodes instructions within each label into binary format, generating separate files for each memory type (e.g., `atomic.bin`, `iram.bin`, `wram.bin`, and `mram.bin`). ### Simulator The simulator receives the linker's output files and input/output data from the host-side virtual machine to emulate UPMEM-PIM behavior and timing. It consists of two primary simulation domains: - **Logic (`uPIMulator/src/device/simulator/dpu/logic.go`):** Evaluates instructions, updates architectural states, and manages threads and their scheduling. - **Memory (`uPIMulator/src/device/simulator/dpu/dram.go`):** Handles data read/write operations, modeling DRAM bank timing using parameters like `t_RAS`, `t_RCD`, `t_CL`, `t_BL`, and `t_RP`. #### Logic Details - **Threads and Thread Scheduler:** - Multiple threads execute PIM kernel portions concurrently, each with its register file and PC. - Thread states: `EMBRYO`, `RUNNABLE`, `SLEEP`, `BLOCK`, and `ZOMBIE`. - Round-robin scheduling with a minimum 11-cycle dispatch interval. - **Logic (`Logic` struct):** - Fetches instructions from the `ThreadScheduler`, processes them through the `Pipeline` and `CycleRule`, and executes them to update architectural states. - `Pipeline`: Models the 14-stage DPU pipeline. - `CycleRule`: Calculates delays to resolve register file conflicts. - `ExecuteFooBar` functions: Perform arithmetic operations, update conditions/flags/PC. #### Memory Details - **DMA (`Dma` struct):** Handles DMA transfers between WRAM and MRAM based on `DmaCommand` from the `Logic`. - **Memory Controller (`MemoryController` struct):** - Receives `DmaCommand` from `Dma`. - Utilizes `MemoryScheduler` to convert `DmaCommand` into `MemoryCommand` sequences. - **Memory Scheduler (`MemoryScheduler` struct):** - Generates `MemoryCommand` (`ACTIVATE`, `READ`, `WRITE`, `PRECHARGE`) and manages open rows using FR-FCFS scheduling. - **Row Buffer (`RowBuffer` struct):** - Models MRAM bank timing, including activation, read/write latencies, and precharge delays. # 🎩 Adding Custom Host-Side API ## Extending the Host-Side API uPIMulator allows you to introduce custom host-side APIs to the virtual machine, enhancing its functionality and adaptability. We'll illustrate this process using the example of adding a `DPU_ASSERT` API, which verifies the success of DPU-related function calls. Note that in the current uPIMulator implementation, these calls always succeed, so `DPU_ASSERT` has no operational effect. However, it serves as a valuable demonstration of the API extension mechanism. ## Steps to Add a New Host-Side API Extending the host-side API involves modifications to several components: 1. **Bytecode Definition:** Introduce a new bytecode instruction to represent the API call. 2. **Interpreter's Codegen:** Implement code generation logic to emit the new bytecode when encountering the API in the host-side C code. 3. **Virtual Machine:** Implement the corresponding behavior for the new bytecode within the virtual machine's execution loop. The following sections will provide code snippets and explanations for each step, guiding you through the process of seamlessly integrating your custom API into uPIMulator. ## Step 1: Define the New Bytecode Opcode The initial step in adding a custom host-side API involves defining a new opcode to represent the API call within uPIMulator's bytecode. ### Location The source code for bytecode opcodes resides in the `uPIMulator/src/host/interpreter/abi` directory. ### Modification - Open the relevant file (`op_code.go`) and locate the `OpCode` enumeration. - Add a new entry for your custom API, in this case, `DPU_ASSERT`, ensuring its placement aligns with the existing opcode naming conventions. ### Example Code Snippet ```go type OpCode int const ( // ... other existing opcodes ... DPU_ASSERT // New opcode for DPU_ASSERT API ) ``` By introducing this new opcode, you establish a unique identifier for the `DPU_ASSERT` API call within the bytecode, paving the way for subsequent steps in the API extension process. ## Step 2: Implement Code Generation for the New API Once the bytecode opcode is defined, the next step involves modifying the interpreter's code generation logic to emit the new bytecode whenever the corresponding API call is encountered in the host-side C code. ### Location The source code for the code generator resides in the `uPIMulator/src/host/interpreter/codegen` directory. ### Modification - Open the `codegen.go` file and locate the `CodegenPostfixExpr` function. - Within this function, add a new case to handle the `DPU_ASSERT` function call. This case should perform the following: 1. Evaluate the function arguments. 2. Emit the newly defined `DPU_ASSERT` bytecode instruction. ### Example Code Snippet ```go // ... other existing cases ... else if func_name == "DPU_ASSERT" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_ASSERT, []int64{}, []string{}) } // ... other existing cases ... ``` This modification ensures that whenever the `DPU_ASSERT` function is called in the host-side C code, the code generator will emit the corresponding bytecode instruction, enabling the virtual machine to handle it appropriately. ## Step 3: Implement Virtual Machine Handling for the New API The final step involves incorporating the handling of the new bytecode instruction into the virtual machine's execution loop. ### Location The virtual machine's core logic resides in the `uPIMulator/src/host/vm/virtual_machine.go` file. ### Modification - Locate the `Advance` function within `virtual_machine.go`. This function is responsible for parsing and executing bytecode instructions. - After the bytecode parsing logic, add a new case to handle the `DPU_ASSERT` opcode. - Within this case, define the desired behavior for the `DpuAssert` function. In the current context, where DPU-related calls always succeed, this function might simply perform a no-op (no operation) or log a message indicating a successful assertion. ### Example Code Snippet ```go // ... other existing cases ... else if bytecode.OpCode() == abi.DPU_ASSERT { this.DpuAssert() } // ... other existing cases ... // ... other existing cases ... func (this *VirtualMachine) DpuAssert() { } // ... other existing cases ... ``` With this modification in place, the virtual machine will execute the `DpuAssert` function whenever it encounters the `DPU_ASSERT` bytecode, effectively integrating your new host-side API into uPIMulator's functionality. Please note that the provided code snippet is illustrative; the actual implementation of `DpuAssert` will depend on the specific behavior you wish to associate with the `DPU_ASSERT` API. # 🎸 Adding custom device-side instructions ## Extending the UPMEM-PIM ISA with Custom Instructions uPIMulator provides the capability to introduce new custom instructions to the UPMEM-PIM ISA, enabling exploration of architectural extensions and potential performance enhancements. We will demonstrate this process by adding a `mul` instruction for 32-bit integer multiplication. While the original ISA achieves this through a sequence of `mul_step` instructions, the new `mul` instruction streamlines the operation into a single instruction. ## Steps to Add a New Instruction Incorporating a new instruction into the UPMEM-PIM ISA within uPIMulator necessitates modifications to the following components: 1. **Linker's Lexer and Parser:** Extend the lexer and parser to recognize and handle the new instruction's syntax. 2. **Linker's Logic:** Implement the corresponding behavior and logic for the new instruction within the linker. 3. **UPMEM-PIM SDK (Optional):** In certain cases, modifications to the UPMEM-PIM SDK might be necessary to support the new instruction at the software level. The following sections will provide code snippets and explanations for each step, guiding you through the process of seamlessly integrating your custom instruction into uPIMulator. ## Step 1: Modify the Assembly Code The initial step involves incorporating the new `mul` instruction into the relevant assembly file. Currently, UPMEM-PIM handles 32-bit integer multiplication using a sequence of `mul_step` instructions defined in `uPIMulator/sdk/syslib/mul32.c`. These instructions are compiled into the object file `uPIMulator/sdk/build/syslib/CMakeFiles/syslib.dir/mulsi32.c.o`. Within this assembly file, you can replace the series of `mul_step` instructions with a single `mul` instruction at the appropriate location (likely Line 22). This modification prepares the assembly code to utilize the new instruction once it is fully supported by the linker and simulator. ```assembly __mulsi3: // @__mulsi3 .Lfunc_begin0: .file 1 "/root/uPIMulator/sdk" "syslib/mul32.c" .loc 1 9 0 // syslib/mul32.c:9:0 .cfi_sections .debug_frame .cfi_startproc // %bb.0: //DEBUG_VALUE: __mulsi3:a <- $r0 //DEBUG_VALUE: __mulsi3:a <- $r0 //DEBUG_VALUE: __mulsi3:b <- $r1 //DEBUG_VALUE: __mulsi3:b <- $r1 .cfi_def_cfa_offset 0 .loc 1 11 5 prologue_end // syslib/mul32.c:11:5 // inline asm jgtu r1, r0, __mulsi3_swap move r2, r0 move r0, r1, true, __mulsi3_start __mulsi3_swap: move r2, r1 move r0, r0 __mulsi3_start: mul r1, r0, r2 __mulsi3_exit: move r0, r1 ``` ## Step 2: Extend the Linker's Lexer To enable the linker to recognize the new `mul` instruction, we need to extend its lexer to include the corresponding token. ### Location The source code defining the linker's tokens is located in the file `uPIMulator/src/device/linker/lexer/token.go`. ### Modification Within this file, add a new token representing the `mul` token to the enumeration (likely around Line 11), ensuring consistent naming and placement with the existing tokens. ### Example Code Snippet ```go type TokenType int const ( // ... other existing tokens ... MUL // New opcode for mul instruction ) ``` This modification equips the lexer with the ability to identify the `mul` instruction during the lexical analysis phase, paving the way for its subsequent parsing and handling within the linker. ## Step 3: Update the Tokenizer After introducing the new token to the lexer, we need to configure the tokenizer to recognize and process it correctly. ### Location The tokenizer's source code is found in the file `uPIMulator/src/device/linker/lexer/tokenizer.go`. ### Modification Within this file, register the new `MUL` token (likely around Line 10) to ensure the tokenizer can identify and classify it during lexical analysis. ### Example Code Snippet ```go func (this *Tokenizer) InitKeywordFactory() { // ... other token registrations ... this.keyword_factory.AddKeyword("mul", MUL) // ... other token registrations ... } ``` This step completes the integration of the new token into the lexer and tokenizer, enabling them to correctly handle the `mul` instruction during the initial stages of the linking process. ## Step 4: Enhance the Parser to Handle the New Instruction Next, we need to modify the parser to correctly parse and interpret the `mul` instruction. ### Location The `mul` instruction has a suffix of `RRR`, indicating that it operates on three registers: one destination register and two source registers. The relevant parsing logic for RRR-type instructions is located in the file `uPIMulator/src/device/linker/parser/expr/rrr_op_code_expr.go`. ### Modification Within this file, add the `MUL` opcode to the appropriate switch case or conditional statement that handles RRR-type instructions. > **Note:** The exact location for adding the opcode might vary depending on the specific structure of the parser code. > If your instruction has a different suffix, you might need to modify a different expression file accordingly. ### Example Code Snippet ```go func (this *RriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.MUL && token_type != lexer.ADD && // ... continue checking the opcode ``` This modification enables the parser to recognize and process the `mul` instruction, extracting its operands and preparing it for further handling by the linker's logic. ## Step 5: Register the New Opcode with the Parser To ensure the parser can correctly handle the `MUL` instruction, we need to explicitly register its opcode within the `Parser` struct. ### Location The `Parser` struct is defined in the file `uPIMulator/src/device/linker/parser/parser.go`. ### Modification Locate the initialization or setup logic for the `Parser` struct, and add the `MUL` opcode to the relevant collection or mapping that tracks supported opcodes (likely around Line 11). ### Example Code Snippet ```go func (this *Parser) RegisterRriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.MUL || token_type == lexer.ADD || // ... continue ... ``` This registration step informs the parser about the existence of the `MUL` opcode, allowing it to invoke the appropriate parsing logic when encountering the `mul` instruction in the assembly code. Please proceed to the next step or feel free to ask any questions! ## Step 6: Implement Instruction Encoding To enable the linker to generate the correct binary representation for the new `mul` instruction, we need to define its encoding scheme. ### Location The instruction encoding logic is located in the file `uPIMulator/src/device/linker/kernel/instruction/op_code.go`. ### Modification Within this file, add the `MUL` opcode to the appropriate data structure or mapping that associates opcodes with their binary encodings (likely around Line 7). Ensure that the encoding adheres to the established conventions for UPMEM-PIM instructions. ### Example Code Snippet ```go type OpCode int const ( // ... other existing opcodes ... MUL // ... other existing opcodes ... } ``` This modification equips the linker with the necessary information to translate the `mul` instruction into its corresponding binary representation during the final encoding phase. ## Step 7: Update Instruction Handling To ensure proper handling of the `MUL` instruction within the simulator, we need to inform the `Instruction` struct about its RRR-type nature and provide a string representation for verbose logging. ### Location The `Instruction` struct and related functions are defined in the file `uPIMulator/src/device/linker/kernel/instruction/instruction.go`. ### Modifications 1. **RRR Opcode Identification:** - Locate the `RrrOpCodes` function within `instruction.go`. - Add the `MUL` opcode to the list of RRR opcodes (likely around Line 3). 2. **Opcode Stringification (Optional):** - If you desire verbose logging of the `MUL` instruction, locate the `StringifyOpcode` function. - Add a case to handle the `MUL` opcode, returning its string representation (e.g., "MUL") (likely around Lines 8-10). ### Example Code Snippets ```go func (this *Instruction) RrrOpCodes() map[OpCode]bool { return map[OpCode]bool{ MUL: true, ADD: true, // ... other existing opcodes ... } } func (this *Instruction) StringifyOpCode() string { // ... other existing opcodes ... else if this.op_code == MUL { return "mul" } // ... other existing opcodes ... ``` These modifications ensure that the `Instruction` struct correctly identifies and handles the `MUL` instruction as an RRR-type operation, and optionally provides a human-readable string representation for verbose logging purposes. ## Step 8: Associate the Token with the Instruction Opcode With the lexer, parser, and encoding in place, we need to establish the connection between the `MUL` token and its corresponding `MUL` opcode within the `InstructionAssigner` struct. ### Location The `InstructionAssigner` struct is defined in the file `uPIMulator/src/device/linker/logic/instruction_assigner.go`. ### Modification Locate the appropriate mapping or data structure within the `InstructionAssigner` that associates tokens with opcodes. Add an entry to link the `MUL` token with the `MUL` opcode (likely around Lines 5-7). ### Example Code Snippet** ```go func (this *InstructionAssigner) ConvertRriOpCode(op_code *expr.Expr) instruction.OpCode { rri_op_code_expr := op_code.RriOpCodeExpr() token_type := rri_op_code_expr.Token().TokenType() // ... other existing opcodes ... else if token_type == lexer.MUL { return instruction.MUL } // ... other existing opcodes ... } ``` This association enables the `InstructionAssigner` to correctly translate the `MUL` token encountered during parsing into the corresponding `MUL` opcode when constructing `Instruction` structs for the simulator. ## Step 9: Implement Instruction Behavior Now, we'll define the functional behavior of the new `mul` instruction, which is to perform a multiplication operation. ### Location The core arithmetic logic unit (ALU) operations are typically implemented within the `Alu` struct, located in the file `uPIMulator/src/device/simulator/dpu/logic/alu.go`. ### Modification Within this file, add a new function or method to the `Alu` struct to handle the `MUL` opcode. This function should implement the 32-bit integer multiplication logic. ### Example Code Snippet** ```go func (this *Alu) Mul(operand1 int64, operand2 int64) { return operand1 * operand2 } ``` This addition equips the ALU with the capability to execute the `mul` instruction, performing the desired multiplication operation when encountered during simulation. ## Step 10: Integrate the Instruction into the Logic The final step is to incorporate the newly defined `mul` instruction handling into the main simulation logic. ### Location The core simulation logic is encapsulated within the `Logic` struct, found in the file `uPIMulator/src/device/simulator/dpu/logic/logic.go`. ### Modification Locate the section within the `Logic` struct's execution loop where instructions are dispatched and executed. Add a case to handle the `MUL` opcode, invoking the `ExecuteMul` function you defined in the `Alu` struct. ### Example Code Snippet** ```go func (this *Logic) ExecuteRrr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } else if instruction_.Suffix() != instruction.RRR { err := errors.New("suffix is not RRR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.MUL { result = this.alu.Mul(ra, rb) carry = false } // ... continue ... } ``` This integration ensures that when the `MUL` instruction is encountered during simulation, the `Logic` struct will delegate its execution to the `Alu` struct's `Mul` function, effectively incorporating the new instruction's behavior into the overall simulation flow. Congratulations! You have now successfully added a custom instruction to the UPMEM-PIM ISA within uPIMulator. Feel free to ask any further questions or seek clarification on any aspect of the process! ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 NR_DPUS ?= 1 PROBLEM_SIZE ?= 2 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) COMMON_INCLUDES := support HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DPROBLEM_SIZE=${PROBLEM_SIZE} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -i 262144 ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/cpu/Makefile ================================================ all: gcc bs_omp.c -o bs_omp -fopenmp run: ./bs_omp 262144 16777216 ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/cpu/README ================================================ Binary Search (BS) Compilation instructions: make Execution instructions ./bs_omp 2048576 16777216 ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/cpu/bs_omp.c ================================================ #include #include #include #include #include #include #include #include #include #include "timer.h" #define DTYPE uint64_t /* * @brief creates a "test file" by filling a bufferwith values */ void create_test_file(DTYPE * input, uint64_t nr_elements, DTYPE * querys, uint64_t n_querys) { uint64_t max = UINT64_MAX; uint64_t min = 0; srand(time(NULL)); input[0] = 1; for (uint64_t i = 1; i < nr_elements; i++) { input[i] = input[i - 1] + (rand() % 10) + 1; } for(uint64_t i = 0; i < n_querys; i++) { querys[i] = input[rand() % (nr_elements - 2)]; } } /** * @brief compute output in the host */ uint64_t binarySearch(DTYPE * input, uint64_t input_size, DTYPE* querys, unsigned n_querys) { uint64_t found = -1; uint64_t q, r, l, m; #pragma omp parallel for private(q,r,l,m) for(q = 0; q < n_querys; q++) { l = 0; r = input_size; while (l <= r) { m = l + (r - l) / 2; // Check if x is present at mid if (input[m] == querys[q]) { found += m; break; } // If x greater, ignore left half if (input[m] < querys[q]) l = m + 1; // If x is smaller, ignore right half else r = m - 1; } } return found; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { Timer timer; uint64_t input_size = atol(argv[1]); uint64_t n_querys = atol(argv[2]); printf("Vector size: %lu, num searches: %lu\n", input_size, n_querys); DTYPE * input = malloc((input_size) * sizeof(DTYPE)); DTYPE * querys = malloc((n_querys) * sizeof(DTYPE)); DTYPE result_host = -1; // Create an input file with arbitrary data. create_test_file(input, input_size, querys, n_querys); start(&timer, 0, 0); result_host = binarySearch(input, input_size - 1, querys, n_querys); stop(&timer, 0); int status = (result_host); if (status) { printf("[OK] Execution time: "); print(&timer, 0, 1); printf("ms.\n"); } else { printf("[ERROR]\n"); } free(input); return status ? 0 : 1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/cpu/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/Makefile ================================================ all: nvcc -arch=sm_30 -m64 -Xcompiler -fPIC -shared -o cu_binary_search.so binary_search.cu -std=c++11 ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/README ================================================ Binary Search (BS) Compilation instructions: make Execution instructions python3 run.py ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/binary_search.cu ================================================ #include #include #include "binary_search.h" #include #include #define BLOCKDIM 512 #define SEARCH_CHUNK 16 #define BLOCK_CHUNK (BLOCKDIM*SEARCH_CHUNK) __global__ void search_kernel(const long int *arr, const long int len, const long int *querys, const long int num_querys, long int *res, bool *flag) { int search; if(*flag == false) { int tid = threadIdx.x; __shared__ int s_arr[BLOCK_CHUNK]; /* Since each value is being copied to shared memory, the rest of the following uncommented code is unncessary, since a direct comparison can be done at the time of copy below. */ // for(int i = 0; i < BLOCKDIM; ++i) { // int shared_loc = i*SEARCH_CHUNK + tid; // int global_loc = shared_loc + BLOCK_CHUNK * blockIdx.x; // if(arr[global_loc] == search) { // *flag = true; // *res = global_loc; // } // __syncthreads(); // } /* Copy chunk of array that this entire block of threads will read from the slower global memory to the faster shared memory. */ for(long int i = 0; i < SEARCH_CHUNK; ++i) { int shared_loc = tid*SEARCH_CHUNK + i; int global_loc = shared_loc + BLOCK_CHUNK * blockIdx.x; /* Make sure to stay within the bounds of the global array, else assign a dummy value. */ if(global_loc < len) { s_arr[shared_loc] = arr[global_loc]; } else { s_arr[shared_loc] = INT_MAX; } } __syncthreads(); for(long int i = 0; i < num_querys; i++) { search = querys[i]; /* For each runtime, set the initial search range. */ int L = 0; int R = SEARCH_CHUNK - 1; int m = (L + R) / 2; /* Pointer to the part of the shared array for this runtime. */ int *s_ptr = &s_arr[tid*SEARCH_CHUNK]; /* Each runtime will search a chunk of the block array. Many blocks will not find a solution so the search must be allowed to fail on a per block basis. The loop will break (fail) when L >= R. */ while(L <= R && *flag == false) { if(s_ptr[m] < search) { L = m + 1; } else if(s_ptr[m] > search) { R = m - 1; } else { *flag = true; *res = m += tid*SEARCH_CHUNK + BLOCK_CHUNK * blockIdx.x; } m = (L + R) / 2; } } } } int binary_search(const long int *arr, const long int len, const long int *querys, const long int num_querys) { long int *d_arr, *d_querys, *d_res; bool *d_flag; size_t arr_size = len * sizeof(long int); size_t querys_size = num_querys * sizeof(long int); size_t res_size = sizeof(long int); size_t flag_size = sizeof(bool); cudaMalloc(&d_arr, arr_size); cudaMalloc(&d_querys, querys_size); cudaMalloc(&d_res, res_size); cudaMalloc(&d_flag, flag_size); cudaMemcpy(d_arr, arr, arr_size, cudaMemcpyHostToDevice); cudaMemcpy(d_querys, querys, querys_size, cudaMemcpyHostToDevice); cudaMemset(d_flag, 0, flag_size); /* Set res value to -1, so that if the function returns -1, that indicates an algorithm failure. */ cudaMemset(d_res, -0x1, res_size); int blockSize = BLOCKDIM; int gridSize = (len-1)/BLOCK_CHUNK + 1; auto start = std::chrono::high_resolution_clock::now(); search_kernel<<>>(d_arr, len, d_querys, num_querys ,d_res, d_flag); cudaDeviceSynchronize(); auto end = std::chrono::high_resolution_clock::now(); std::cout << "Kernel Time: " << std::chrono::duration_cast(end-start).count() << " ms" << std::endl; long int res; cudaMemcpy(&res, d_res, res_size, cudaMemcpyDeviceToHost); return res; } ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/binary_search.h ================================================ #ifndef BINARY_SEARCH_H #define BINARY_SEARCH_H #ifdef _WIN32 #include #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT #endif extern "C" { int DLL_EXPORT binary_search(const long int *arr, const long int len, const long int *querys, const long int num_querys); } #endif /* BINARY_SEARCH_H */ ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/cpu_lib.py ================================================ # -*- coding: utf-8 -*- def binary_search(arr, search): L = 0 R = len(arr) while L <= R: if L > R: return -1 # Error code 1 m = (L + R) / 2 if arr[m] < search: L = m + 1 elif arr[m] > search: R = m - 1 else: return m return -2 # Error code 2 ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/cu_lib_import.py ================================================ # -*- coding: utf-8 -*- __all__ = [ "binary_search", ] import os.path as path import platform from ctypes import * from numpy.ctypeslib import load_library, ndpointer ## Load the DLL if platform.system() == "Linux": cuda_lib = load_library("cu_binary_search.so", path.dirname(path.realpath(__file__))) elif platform.system() == "Windows": cuda_lib = load_library("cu_binary_search.dll", path.dirname(path.realpath(__file__))) ## Define argtypes for all functions to import argtype_defs = { "binary_search": [ndpointer("i8"), c_int, ndpointer("i8"), c_int], } ## Import functions from DLL for func, argtypes in argtype_defs.items(): locals().update({func: cuda_lib[func]}) locals()[func].argtypes = argtypes ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/baselines/gpu/run.py ================================================ # -*- coding: utf-8 -*- import time import numpy as np # Local Imports from cu_lib_import import binary_search as gpu_search # Set an array label to create arr_len = 2048576 num_querys = 16777216 # Dummy array created arr = np.arange(0, arr_len, 1).astype("i8") # Random search querys created querys = np.random.randint(1, arr_len, num_querys) # GPU search function call t0 = time.time() res_gpu = gpu_search(arr, len(arr), querys, len(querys)) print("Total GPU Time: %i ms" % ((time.time() - t0) * 1e003)) ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/dpu/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/BS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS}") file(GLOB_RECURSE SRCS *.c) add_executable(BS_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/dpu/task.c ================================================ /* * Binary Search with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Search DTYPE __attribute__ ((noinline)) search(DTYPE *bufferA, DTYPE searching_for) { DTYPE found = -2; if(bufferA[0] <= searching_for) { found = -1; for (uint32_t i = 0; i < BLOCK_SIZE / sizeof(DTYPE); i++){ if(bufferA[i] == searching_for) { found = i; break; } } } return found; } BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int(*kernels[nr_kernels])(void) = {main_kernel1}; int main(void){ // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if(tasklet_id == 0){ mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); DTYPE searching_for, found; uint64_t input_size = DPU_INPUT_ARGUMENTS.input_size; // Address of the current processing block in MRAM uint32_t start_mram_block_addr_A = (uint32_t) DPU_MRAM_HEAP_POINTER; uint32_t start_mram_block_addr_aux = start_mram_block_addr_A; uint32_t end_mram_block_addr_A = start_mram_block_addr_A + sizeof(DTYPE) * input_size; uint32_t current_mram_block_addr_query = end_mram_block_addr_A + tasklet_id * (DPU_INPUT_ARGUMENTS.slice_per_dpu / NR_TASKLETS) * sizeof(DTYPE); // Initialize a local cache to store the MRAM block DTYPE *cache_A = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_aux_A = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_aux_B = (DTYPE *) mem_alloc(BLOCK_SIZE); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; // TODO(bongjoon.hyun@gmail.com): original PrIM benchmark uses uint64_t for targets' type for(uint32_t targets = 0; targets < (DPU_INPUT_ARGUMENTS.slice_per_dpu / NR_TASKLETS); targets++) { found = -1; mram_read((__mram_ptr void const *) current_mram_block_addr_query, &searching_for, 8); current_mram_block_addr_query += 8; bool end = false; // Initialize input vector boundaries start_mram_block_addr_A = (uint32_t) DPU_MRAM_HEAP_POINTER; start_mram_block_addr_aux = start_mram_block_addr_A; end_mram_block_addr_A = start_mram_block_addr_A + sizeof(DTYPE) * input_size; uint32_t current_mram_block_addr_A = start_mram_block_addr_A; // Bring first and last values to WRAM mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_aux_A, BLOCK_SIZE); mram_read((__mram_ptr void const *) (end_mram_block_addr_A - BLOCK_SIZE * sizeof(DTYPE)), cache_aux_B, BLOCK_SIZE); current_mram_block_addr_A = (start_mram_block_addr_A + end_mram_block_addr_A) / 2; while(!end) { // Load cache with current MRAM block mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_A, BLOCK_SIZE); // Search inside block found = search(cache_A, searching_for); // If found > -1, we found the searching_for query if(found > -1) { result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); break; } // If found == -2, we need to discard right part of the input vector if(found == -2) { end_mram_block_addr_A = current_mram_block_addr_A; current_mram_block_addr_A = (current_mram_block_addr_A + start_mram_block_addr_A) / 2; } // If found == -1, we need to discard left part of the input vector else if (found == -1) { start_mram_block_addr_A = current_mram_block_addr_A; current_mram_block_addr_A = (current_mram_block_addr_A + end_mram_block_addr_A) / 2; } // Start boundary check if(current_mram_block_addr_A < (start_mram_block_addr_aux + BLOCK_SIZE)) { end = true; mram_read((__mram_ptr void const *) current_mram_block_addr_A, cache_A, BLOCK_SIZE); found = search(cache_A, searching_for); if(found > -1) { end = true; result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); } } // End boundary check if(current_mram_block_addr_A > (end_mram_block_addr_A - BLOCK_SIZE)) { end = true; mram_read((__mram_ptr void const *) end_mram_block_addr_A - BLOCK_SIZE, cache_A, BLOCK_SIZE); found = search(cache_A, searching_for); if(found > -1) { result->found = found + (current_mram_block_addr_A - start_mram_block_addr_aux) / sizeof(DTYPE); } } } } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 struct dpu_arguments_t{ long input_size; long slice_per_dpu; int kernel; }; struct dpu_results_t { long found; }; void create_test_file(long * input, long * querys, long nr_elements, long nr_querys) { input[0] = 1; for (long i = 1; i < nr_elements; i++) { input[i] = input[i - 1] + 1; } for (long i = 0; i < nr_querys; i++) { querys[i] = i; } } long binarySearch(long * input, long * querys, long input_size, long num_querys) { long result = -1; long r; for(long q = 0; q < num_querys; q++) { long l = 0; r = input_size; while (l <= r) { long m = l + (r - l) / 2; if (input[m] == querys[q]) { result = m; } if (input[m] < querys[q]) { l = m + 1; } else { r = m - 1; } } } return result; } int main() { struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; long input_size = DATA_PREP_PARAMS; long num_querys = DATA_PREP_PARAMS / 8; long result_host = -1; long result_dpu = -1; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); if(num_querys % (nr_of_dpus * NUM_TASKLETS)) { num_querys = num_querys + (nr_of_dpus * NUM_TASKLETS - num_querys % (nr_of_dpus * NUM_TASKLETS)); } assert(num_querys % (nr_of_dpus * NUM_TASKLETS) == 0); long * input = malloc((input_size) * sizeof(long)); long * querys = malloc((num_querys) * sizeof(long)); create_test_file(input, querys, input_size, num_querys); result_host = binarySearch(input, querys, input_size - 1, num_querys); long slice_per_dpu = num_querys / nr_of_dpus; struct dpu_arguments_t input_arguments; input_arguments.input_size = input_size; input_arguments.slice_per_dpu = slice_per_dpu; input_arguments.kernel = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, input); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size * sizeof(long), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &querys[slice_per_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, input_size * sizeof(long), slice_per_dpu * sizeof(long), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_results_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_results_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_results_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for(int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(results_retrieve[i * NUM_TASKLETS + each_tasklet].found > result_dpu) { result_dpu = results_retrieve[i * NUM_TASKLETS + each_tasklet].found; } } } int status = (result_dpu == result_host); assert(status); free(input); dpu_free(dpu_set); return status ? 0 : 1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ #ifdef TL #define TASKLETS_INITIALIZER TASKLETS(TL, main, 2048, 2) #define NB_OF_TASKLETS_PER_DPU TL #else #define TASKLETS_INITIALIZER TASKLETS(16, main, 2048, 2) #define NB_OF_TASKLETS_PER_DPU 16 #endif // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #endif // Data type #define DTYPE int64_t // Vector size #define INPUT_SIZE 2048576 typedef struct { uint64_t input_size; uint64_t slice_per_dpu; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; // Structures used by both the host and the dpu to communicate information typedef struct { DTYPE found; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { long num_querys; unsigned n_warmup; unsigned n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i problem size (default=2 queries)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.num_querys = PROBLEM_SIZE; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "h:i:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.num_querys = atol(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/BS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) project(benchmark) add_subdirectory(BS) add_subdirectory(GEMV) add_subdirectory(HST-L) add_subdirectory(HST-S) add_subdirectory(MLP) add_subdirectory(RED) add_subdirectory(SCAN-RSS) add_subdirectory(SCAN-SSA) add_subdirectory(SEL) add_subdirectory(TRNS) add_subdirectory(TS) add_subdirectory(UNI) add_subdirectory(VA) add_subdirectory(VA_SIMPLE) ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -m 1024 -n 1024 ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_10_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_11_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_12_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_13_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_14_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_15_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_16 ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_16_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_17_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_18_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_19_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_1_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_20_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_21_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_22_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_23_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_24_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_2_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_3_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_4_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_5_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_6_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_7_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_8_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/_NR_TASKLETS_9_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/cpu/Makefile ================================================ all: gcc -o gemv -fopenmp gemv_openmp.c clean: rm gemv ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/cpu/README ================================================ Matrix-Vector Multiplication (GEMV) Compilation instructions: make Execution instructions ./gemv ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/cpu/gemv_openmp.c ================================================ #include #include #include "../../support/timer.h" #include "gemv_utils.h" int main(int argc, char *argv[]) { const size_t rows = 20480; const size_t cols = 8192; double **A, *b, *x; b = (double*) malloc(sizeof(double)*rows); x = (double*) malloc(sizeof(double)*cols); allocate_dense(rows, cols, &A); make_hilbert_mat(rows,cols, &A); #pragma omp parallel { #pragma omp for for (size_t i = 0; i < cols; i++) { x[i] = (double) i+1 ; } #pragma omp for for (size_t i = 0; i < rows; i++) { b[i] = (double) 0.0; } } Timer timer; start(&timer, 0, 0); gemv(A, x, rows, cols, &b); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); #if 0 print_vec(x, rows); print_mat(A, rows, cols); print_vec(b, rows); #endif printf("sum(x) = %f, sum(Ax) = %f\n", sum_vec(x,cols), sum_vec(b,rows)); return 0; } void gemv(double** A, double* x, size_t rows, size_t cols, double** b) { #pragma omp parallel for for (size_t i = 0; i < rows; i ++ ) for (size_t j = 0; j < cols; j ++ ) { (*b)[i] = (*b)[i] + A[i][j]*x[j]; } } void make_hilbert_mat(size_t rows, size_t cols, double*** A) { #pragma omp parallel for for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < cols; j++) { (*A)[i][j] = 1.0/( (double) i + (double) j + 1.0); } } } double sum_vec(double* vec, size_t rows) { double sum = 0.0; #pragma omp parallel for reduction(+:sum) for (int i = 0; i < rows; i++) sum = sum + vec[i]; return sum; } ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/cpu/gemv_utils.h ================================================ void allocate_dense(size_t rows,size_t cols, double*** dense) { *dense = malloc(sizeof(double)*rows); **dense = malloc(sizeof(double)*rows*cols); for (size_t i=0; i < rows; i++ ) { (*dense)[i] = (*dense)[0] + i*cols; } } void print_mat(double** A, size_t rows, size_t cols) { for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < cols; j++) { printf("%f ", A[i][j]); } printf("\n"); } } void print_vec(double* b, size_t rows) { for (size_t i = 0; i < rows; i++) { printf("%f\n", b[i]); } } void gemv(double** A, double* x, size_t rows, size_t cols, double** b); void make_hilbert_mat(size_t rows, size_t cols, double*** A); double sum_vec(double* vec, size_t rows); ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc gemv.cu -I/usr/local/cuda/include -lm -o gemv clean: rm gemv ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/gpu/README ================================================ Matrix-Vector Multiplication (GEMV) Compilation instructions: make Execution instructions ./gemv ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/baselines/gpu/gemv.cu ================================================ #include #include #include #include #define THREAD 128 #define T int __global__ void gemv(int m, int n, T *adim, T *b, T *d_ans); void cgemv(int m, int n, T *adim, T *b, T *d_ans); double gettime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1.0e-6; } int main(int argc, char **argv) { /* for CPU */ int i, j; int *bdim, *c, *ans, *h_ans; //double start, stop; //double cpu_time, gpu_time; int n = 8192; int m = 20480; bdim = (T*)malloc(sizeof(T) *m*n); c = (T*)malloc(sizeof(T) *n); ans = (T*)malloc(sizeof(T) *m); h_ans = (T*)malloc(sizeof(T) *m); /* for GPU */ T *d_bdim, *d_c, *d_ans; cudaMalloc((void **)&d_bdim, sizeof(T)*m*n); cudaMalloc((void **)&d_c, sizeof(T)*n); cudaMalloc((void **)&d_ans, sizeof(T)*m); for(i = 0; i < n; i++) { c[i] = 1; for(j = 0; j < m; j++) bdim[i*m+j] = 1; } //start = gettime(); cgemv(m, n, bdim, c, ans); //stop = gettime(); //cpu_time=stop - start; // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; cudaMemcpy(d_bdim, bdim, sizeof(T)*m*n, cudaMemcpyHostToDevice); cudaMemcpy(d_c, c, sizeof(T)*n, cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); //start = gettime(); gemv<<>>(m, n, d_bdim, d_c, d_ans); //stop = gettime(); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); //gpu_time=stop - start; cudaMemcpy(h_ans, d_ans, sizeof(T)*m, cudaMemcpyDeviceToHost); //printf("cpu_time : %.6f[sec]\n",cpu_time); //printf("gpu_time : %.6f[sec]\n",gpu_time); //printf("%f x\n", cpu_time / gpu_time); for(i = 0; i < m; i++) printf("%d -- %d\n", ans[i], h_ans[i]); printf("Execution time = %f ms\n", time1); free(bdim); free(c); free(ans); free(h_ans); cudaFree(d_bdim); cudaFree(d_c); cudaFree(d_ans); return 0; } __global__ void gemv(int m, int n, T* adim, T* b, T* d_ans) { int i; int div = n/THREAD; __shared__ T tmp[THREAD]; tmp[threadIdx.x] = 0.0; for(i = 0; i < div; i++) { tmp[threadIdx.x] += adim[blockIdx.x*n+i*THREAD+threadIdx.x] * b[i * THREAD + threadIdx.x]; } if(threadIdx.x < m%THREAD) tmp[threadIdx.x] += adim[blockIdx.x*n+THREAD*div+threadIdx.x] * b[THREAD * div + threadIdx.x]; __syncthreads(); for(i = THREAD / 2; i > 31; i = i / 2) { if(threadIdx.x < i) tmp[threadIdx.x] += tmp[threadIdx.x + i]; __syncthreads(); } if(threadIdx.x < 16) { tmp[threadIdx.x] += tmp[threadIdx.x + 16]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 8]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 4]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 2]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 1]; __syncthreads(); } if(threadIdx.x == 0) d_ans[blockIdx.x] = tmp[0]; } void cgemv(int m, int n, T *adim, T *b, T *d_ans) { int i, j; for(i = 0; i < m; i++) for(j = 0; j < n; j++) d_ans[i] += adim[i*n+j] * b[j]; } ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/GEMV/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(GEMV_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/dpu/task.c ================================================ /* * Matrix vector multiplication with multiple tasklet * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // GEMV void __attribute__ ((noinline)) gemv(T *bufferC, T *bufferA, T *bufferB, int pos) { for (unsigned int i = 0; i < BLOCK_SIZE / sizeof(T); i++) { bufferC[pos] += bufferA[i] * bufferB[i]; } return; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // main int main() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); int32_t n_size = DPU_INPUT_ARGUMENTS.n_size; int32_t n_size_pad = DPU_INPUT_ARGUMENTS.n_size_pad; uint32_t nr_rows = DPU_INPUT_ARGUMENTS.nr_rows; uint32_t max_rows = DPU_INPUT_ARGUMENTS.max_rows; unsigned int nrows = nr_rows; unsigned int rows_per_tasklet; unsigned int start_row; unsigned int chunks = nrows / (NR_TASKLETS + NR_TASKLETS); unsigned int dbl_chunks = chunks + chunks; rows_per_tasklet = dbl_chunks; unsigned int rest_rows = nrows % (NR_TASKLETS + NR_TASKLETS); if ((tasklet_id + tasklet_id) < rest_rows) rows_per_tasklet += 2; if (rest_rows > 0) { if ((tasklet_id + tasklet_id) >= rest_rows) { unsigned int hlf_rest_rows = rest_rows >> 1; if ((rest_rows & 1) == 1) start_row = (hlf_rest_rows + 1) * (dbl_chunks + 2) + (tasklet_id - 1 - hlf_rest_rows) * dbl_chunks; else start_row = (hlf_rest_rows) * (dbl_chunks + 2) + (tasklet_id - hlf_rest_rows) * dbl_chunks; } else start_row = tasklet_id * (dbl_chunks + 2); } else { start_row = tasklet_id * (dbl_chunks); } // Address of the current row in MRAM uint32_t mram_base_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + start_row * n_size * sizeof(T)); uint32_t mram_base_addr_B = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T)); uint32_t mram_base_addr_C = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T) + n_size_pad * sizeof(T) + start_row * sizeof(T)); uint32_t mram_temp_addr_A = mram_base_addr_A; uint32_t mram_temp_addr_B = mram_base_addr_B; // Inititalize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE + 8); T *cache_A_aux = (T *) mem_alloc(8); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); T *cache_C = (T *) mem_alloc(8); int offset = 0; // Iterate over nr_rows for (unsigned int i = start_row; i < start_row + rows_per_tasklet; i += 2) { mram_temp_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + i * n_size * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; cache_C[0] = 0; cache_C[1] = 0; for(unsigned int pos = 0; pos < 2 && i + pos < nr_rows; pos++){ int n = 0, j; for (n = 0; n < (int32_t) (n_size - (BLOCK_SIZE/sizeof(T))); n += (BLOCK_SIZE / sizeof(T))) { mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) - 1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } // Compute GEMV gemv(cache_C, cache_A, cache_B, pos); // Update memory addresses mram_temp_addr_A += BLOCK_SIZE; mram_temp_addr_B += BLOCK_SIZE; } mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) -1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE ), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); for (j = 0; j < (int) (n_size - n); j++) { // Compute GEMV if(j >= (int)(BLOCK_SIZE / sizeof(T))){ printf("error\n"); break; } cache_C[pos] += cache_A[j] * cache_B[j]; } mram_temp_addr_A += (BLOCK_SIZE - ((BLOCK_SIZE / sizeof(T)) - (n_size - n)) * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; if(mram_temp_addr_A % 8 != 0) { offset = 1; } else { offset = 0; } } // Write cache to current MRAM block mram_write(cache_C, (__mram_ptr void *) (mram_base_addr_C), 8); // Update memory address mram_base_addr_C += 2 * sizeof(T); } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 struct dpu_arguments_t { int n_size; int n_size_pad; int nr_rows; int max_rows; }; struct dpu_info_t { int rows_per_dpu; int rows_per_dpu_pad; int prev_rows_dpu; }; void init_data(int* A, int* B, int m_size, int n_size) { for (int i = 0; i < m_size * n_size; i++) { A[i] = i % 50; } for (int i = 0; i < n_size; i++) { B[i] = i % 50; } } void gemv_host(int* C, int* A, int* B, int m_size, int n_size) { for (int i = 0; i < m_size; i++) { C[i] = 0; } for (int m = 0; m < m_size; m++) { for (int n = 0; n < n_size; n++) { C[m] += A[m * n_size + n] * B[n]; } } } int main() { int* A; int* B; int* C; int* C_dpu; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NR_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int i; int m_size = DATA_PREP_PARAMS; int n_size = 64; struct dpu_info_t* dpu_info = malloc(nr_of_dpus * sizeof(struct dpu_info_t)); struct dpu_arguments_t *input_args = malloc(nr_of_dpus * sizeof(struct dpu_arguments_t)); int max_rows_per_dpu = 0; int n_size_pad = n_size; if(n_size % 2 == 1) { n_size_pad++; } DPU_FOREACH(dpu_set, dpu, i) { int rows_per_dpu; int prev_rows_dpu = 0; int chunks = m_size / nr_of_dpus; rows_per_dpu = chunks; int rest_rows = m_size % nr_of_dpus; if (i < rest_rows) { rows_per_dpu++; } if (rest_rows > 0) { if (i >= rest_rows) { prev_rows_dpu = rest_rows * (chunks + 1) + (i - rest_rows) * chunks; } else { prev_rows_dpu = i * (chunks + 1); } } else { prev_rows_dpu = i * chunks; } int rows_per_dpu_pad = rows_per_dpu; if (rows_per_dpu_pad % 2 == 1) { rows_per_dpu_pad++; } if (rows_per_dpu_pad > max_rows_per_dpu) { max_rows_per_dpu = rows_per_dpu_pad; } dpu_info[i].rows_per_dpu = rows_per_dpu; dpu_info[i].rows_per_dpu_pad = rows_per_dpu_pad; dpu_info[i].prev_rows_dpu = prev_rows_dpu; input_args[i].n_size = n_size; input_args[i].n_size_pad = n_size_pad; input_args[i].nr_rows = rows_per_dpu; } A = malloc(max_rows_per_dpu * nr_of_dpus * n_size_pad * sizeof(int)); B = malloc(n_size_pad * sizeof(int)); C = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(int)); init_data(A, B, m_size, n_size); gemv_host(C, A, B, m_size, n_size); DPU_FOREACH(dpu_set, dpu, i) { input_args[i].max_rows = max_rows_per_dpu; dpu_prepare_xfer(dpu, &input_args[i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &A[dpu_info[i].prev_rows_dpu * n_size]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(int), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, B); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) , n_size_pad * sizeof(int), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); C_dpu = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(int)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &C_dpu[i * max_rows_per_dpu]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) + n_size_pad * sizeof(int), max_rows_per_dpu * sizeof(int), DPU_XFER_DEFAULT); int status = 1; i = 0; for (int n = 0; n < nr_of_dpus; n++) { for (int j = 0; j < dpu_info[n].rows_per_dpu; j++) { if(C[i] != C_dpu[n * max_rows_per_dpu + j]) { status = 0; } i++; } } assert(status); free(A); free(B); free(C); free(C_dpu); dpu_free(dpu_set); return status ? 0 : -1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t n_size; uint32_t n_size_pad; uint32_t nr_rows; uint32_t max_rows; } dpu_arguments_t; // Specific information for each DPU struct dpu_info_t { uint32_t rows_per_dpu; uint32_t rows_per_dpu_pad; uint32_t prev_rows_dpu; }; struct dpu_info_t *dpu_info; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int m_size; unsigned int n_size; unsigned int n_warmup; unsigned int n_reps; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -m m_size (default=8192 elements)" "\n -n n_size (default=8192 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.m_size = 8192; p.n_size = 8192; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hm:n:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'm': p.m_size = atoi(optarg); break; case 'n': p.n_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/GEMV/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); //printf("Time (ms): %f\t",((timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + // (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec)) / 1000); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 8 NR_DPUS ?= 1 NR_HISTO ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_NR_DPUS_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${NR_DPUS}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -DNR_HISTO=${NR_HISTO} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(NR_HISTO 1) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/HST-L/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -DNR_HISTO=${NR_HISTO}") file(GLOB_RECURSE SRCS *.c) add_executable(HST-L_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/dpu/task.c ================================================ /* * Histogram (HST-L) with multiple tasklets * */ #include #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // Array for communication between adjacent tasklets uint32_t* message[NR_TASKLETS]; // DPU histogram uint32_t* histo_dpu; // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); ATOMIC_BIT_INIT(barriers_mutexes)[NR_HISTO]; barrier_t barriers[NR_HISTO]; // Mutex mutex_id_t my_mutex[NR_HISTO]; // Histogram in each tasklet void __attribute__ ((noinline)) histogram(uint32_t* histo, uint32_t bins, T *input, uint32_t histo_id, unsigned int l_size){ for(unsigned int j = 0; j < l_size; j++) { T d = (input[j] * bins) >> DEPTH; mutex_lock(my_mutex[histo_id]); histo[d] += 1; mutex_unlock(my_mutex[histo_id]); } } extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif unsigned int l_tasklet_id = tasklet_id / NR_HISTO; unsigned int nr_l_tasklet = NR_TASKLETS / NR_HISTO; unsigned int my_histo_id = tasklet_id & (NR_HISTO - 1); if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap // Initialize barriers for (unsigned int each_barrier = 0; each_barrier < NR_HISTO; each_barrier++) { barriers[each_barrier].wait_queue = 0xff; barriers[each_barrier].count = nr_l_tasklet; barriers[each_barrier].initial_count = nr_l_tasklet; barriers[each_barrier].lock = (uint8_t) &ATOMIC_BIT_GET(barriers_mutexes)[each_barrier]; } } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes uint32_t bins = DPU_INPUT_ARGUMENTS.bins; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_histo = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local histogram if (tasklet_id < NR_HISTO){ // Allocate DPU histogram uint32_t *histo = (uint32_t *) mem_alloc(bins * sizeof(uint32_t)); message[tasklet_id] = histo; } // Barrier barrier_wait(&barriers[my_histo_id]); uint32_t *my_histo = message[my_histo_id]; // Initialize local histogram for(unsigned int i = l_tasklet_id; i < bins; i += nr_l_tasklet){ my_histo[i] = 0; } // Barrier barrier_wait(&barriers[my_histo_id]); // Compute histogram for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Histogram in each tasklet histogram(my_histo, bins, cache_A, my_histo_id, l_size_bytes >> DIV); } // Barrier barrier_wait(&my_barrier); uint32_t *histo_dpu = message[0]; for (unsigned int i = tasklet_id; i < bins; i += NR_TASKLETS){ uint32_t b = 0; for (unsigned int j = 0; j < NR_HISTO; j++){ b += *(message[j] + i); } histo_dpu[i] = b; } // Barrier barrier_wait(&my_barrier); // Write dpu histogram to current MRAM block if(tasklet_id == 0){ if(bins * sizeof(uint32_t) <= 2048) mram_write(histo_dpu, (__mram_ptr void*)(mram_base_addr_histo), bins * sizeof(uint32_t)); else for(unsigned int offset = 0; offset < ((bins * sizeof(uint32_t)) >> 11); offset++){ mram_write(histo_dpu + (offset << 9), (__mram_ptr void*)(mram_base_addr_histo + (offset << 11)), 2048); } } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define DEPTH 12 struct dpu_arguments_t { int size; int transfer_size; int bins; int kernel; }; void read_input(int* A, int input_size) { for (int i = 0; i < input_size; i++) { A[i] = i % 4096; } } void histogram_host(int* histo, int* A, int bins, int nr_elements, int exp, int nr_of_dpus) { if(!exp){ for (int i = 0; i < nr_of_dpus; i++) { for (int j = 0; j < nr_elements; j++) { int d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ for (int j = 0; j < nr_elements; j++) { int d = A[j]; histo[(d * bins) >> DEPTH] += 1; } } } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { int* A; int* histo_host; int* histo; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int input_size = DATA_PREP_PARAMS; int input_size_8bytes = ((input_size * sizeof(int)) % 8) != 0 ? roundup(input_size, 8) : input_size; int input_size_dpu = divceil(input_size, nr_of_dpus); int input_size_dpu_8bytes = ((input_size_dpu * sizeof(int)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; int bins = 256; A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); int *bufferA = A; histo_host = malloc(bins * sizeof(int)); histo = malloc(nr_of_dpus * bins * sizeof(int)); read_input(A, input_size); for (int i = 0; i < bins; i++) { histo_host[i] = 0; } for (int i = 0; i < nr_of_dpus * bins; i++) { histo[i] = 0; } histogram_host(histo_host, A, bins, input_size, 1, nr_of_dpus); int kernel = 0; struct dpu_arguments_t* input_arguments = malloc(NUM_DPUS * sizeof(struct dpu_arguments_t)); for(int i=0; i profile/HSTL_${b}_tl${k}_dpu${i}.txt wait make clean wait done done done ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #define REGS (BLOCK_SIZE >> 2) // 32 bits // Pixel depth #define DEPTH 12 #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; uint32_t transfer_size; uint32_t bins; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int dpu_s; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1, 2) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.file_name = "./input/image_VanHateren.iml"; p.dpu_s = 64; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:z:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 'z': p.dpu_s = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-L/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/cpu/Makefile ================================================ all: gcc -o hist -fopenmp app_baseline.c clean: rm hist ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/cpu/README ================================================ Histogram - input partition (HST) Compilation instructions: make Execution instructions ./hist -y 1006632960 -t 4 For more options: ./hsti -h ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/cpu/app_baseline.c ================================================ /* * JGL@SAFARI */ /** * @file app.c * @brief Template for a Host Application Source File. * * The macros DPU_BINARY and NR_TASKLETS are directly * used in the static functions, and are not passed as arguments of these functions. */ #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" // Pointer declaration static T* A; static unsigned int* histo_host; typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int n_threads; }Params; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, const Params p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, p.file_name); if((File = fopen(dctFileName, "rb")) != NULL) { for(unsigned int y = 0; y < p.input_size; y++) { fread(&temp, sizeof(unsigned short), 1, File); A[y] = (unsigned int)ByteSwap16(temp); if(A[y] >= 4096) A[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } /** * @brief compute output in the host */ static void histogram_host(unsigned int* histo, T* A, unsigned int bins, unsigned int nr_elements, int exp, unsigned int nr_of_dpus, int t) { omp_set_num_threads(t); if(!exp){ #pragma omp parallel for for (unsigned int i = 0; i < nr_of_dpus; i++) { for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ #pragma omp parallel for for (unsigned int j = 0; j < nr_elements; j++) { T d = A[j]; #pragma omp atomic update histo[(d * bins) >> DEPTH] += 1; } } } // Params --------------------------------------------------------------------- void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -t # of threads (default=8)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 8; p.exp = 1; p.file_name = "../../input/image_VanHateren.iml"; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); uint32_t nr_of_dpus; const unsigned int input_size = p.input_size; // Size of input image if(!p.exp) assert(input_size % p.n_threads == 0 && "Input size!"); else assert(input_size % p.n_threads == 0 && "Input size!"); // Input/output allocation A = malloc(input_size * sizeof(T)); T *bufferA = A; if(!p.exp) histo_host = malloc(nr_of_dpus * p.bins * sizeof(unsigned int)); else histo_host = malloc(p.bins * sizeof(unsigned int)); // Create an input file with arbitrary data. read_input(A, p); Timer timer; start(&timer, 0, 0); if(!p.exp) memset(histo_host, 0, nr_of_dpus * p.bins * sizeof(unsigned int)); else memset(histo_host, 0, p.bins * sizeof(unsigned int)); histogram_host(histo_host, A, p.bins, input_size, p.exp, nr_of_dpus, p.n_threads); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=/usr/local/cuda/bin/nvcc CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -L/usr/local/cuda/lib64 -lm INC=-I/usr/local/cuda/include DEP=kernel.cpp kernel.h main.cpp kernel.cu support/common.h support/cuda-setup.h support/partitioner.h support/timer.h support/verify.h SRC=main.cpp kernel.cpp kernel.cu EXE=hsti all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) $(INC) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/README ================================================ Histogram - input partition (HST) Compilation instructions: make Execution instructions ./hsti -n 1006632960 -g 512 For more options: ./hsti -h Note: The input folder contains one image from Van Hateren's natural image database (http://www.kyb.tuebingen.mpg.de/?id=227). Image pixels are 12-bit depth. Thus, for calculation of the B-bin histogram of an image, the corresponding histogram bin is computed as ((pixel * B) >> 12). Monochrome images from other databases or synthetic images can also be used. The read input function (in main.cpp) might need to be changed accordingly. If image pixels are b-bit depth and the histogram contains B bins, the histogram bin will be computed as ((pixel * B) >> b). ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "kernel.h" #include "support/partitioner.h" #include #include #include #include // CPU threads-------------------------------------------------------------------------------------- void run_cpu_threads(std::atomic_uint *histo, unsigned int *data, int size, int bins, int n_threads, int chunk, int n_tasks, float alpha #ifdef CUDA_8_0 , std::atomic_int *worklist #endif ) { std::vector cpu_threads; for(int k = 0; k < n_threads; k++) { cpu_threads.push_back(std::thread([=]() { #ifdef CUDA_8_0 Partitioner p = partitioner_create(n_tasks, alpha, k, n_threads, worklist); #else Partitioner p = partitioner_create(n_tasks, alpha, k, n_threads); #endif unsigned int Hs[bins]; // Local histogram initialization for(int i = 0; i < bins; i++) { Hs[i] = 0; } for(int i = cpu_first(&p); cpu_more(&p); i = cpu_next(&p)) { for(int j = 0; j < chunk; j++) { // Read pixel unsigned int d = ((data[i * chunk + j] * bins) >> 12); // Vote in histogram Hs[d]++; } } // Merge to global histogram for(int i = 0; i < bins; i++) { (&histo[i])->fetch_add(Hs[i]); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.cu ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #define _CUDA_COMPILER_ #include "support/common.h" #include "support/partitioner.h" // CUDA kernel ------------------------------------------------------------------------------------------ __global__ void Histogram_kernel(int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo #ifdef CUDA_8_0 , int *worklist #endif ) { extern __shared__ unsigned int l_mem[]; unsigned int* l_histo = l_mem; #ifdef CUDA_8_0 int* l_tmp = (int*)&l_histo[bins]; #endif #ifdef CUDA_8_0 Partitioner p = partitioner_create(n_tasks, alpha, worklist, l_tmp); #else Partitioner p = partitioner_create(n_tasks, alpha); #endif // Block and runtime index const int bx = blockIdx.x; const int tx = threadIdx.x; const int bD = blockDim.x; const int gD = gridDim.x; // Sub-histograms initialization for(int pos = tx; pos < bins; pos += bD) { l_histo[pos] = 0; } __syncthreads(); // Intra-block synchronization // Main loop for(int i = gpu_first(&p); gpu_more(&p); i = gpu_next(&p)) { // Global memory read unsigned int d = data[i * bD + tx]; // Atomic vote in shared memory atomicAdd(&l_histo[((d * bins) >> 12)], 1); } __syncthreads(); // Intra-block synchronization // Merge per-block histograms and write to global memory for(int pos = tx; pos < bins; pos += bD) { // Atomic addition in global memory #ifdef CUDA_8_0 atomicAdd_system(histo + pos, l_histo[pos]); #else atomicAdd(histo + pos, l_histo[pos]); #endif } } cudaError_t call_Histogram_kernel(int blocks, int threads, int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo, int l_mem_size #ifdef CUDA_8_0 , int* worklist #endif ){ dim3 dimGrid(blocks); dim3 dimBlock(threads); Histogram_kernel<<>>(size, bins, n_tasks, alpha, data, histo #ifdef CUDA_8_0 , worklist #endif ); cudaError_t err = cudaGetLastError(); return err; } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include "support/common.h" void run_cpu_threads(std::atomic_uint *histo, unsigned int *data, int size, int bins, int num_threads, int chunk, int n_tasks, float alpha #ifdef CUDA_8_0 , std::atomic_int *wl #endif ); cudaError_t call_Histogram_kernel(int blocks, int threads, int size, int bins, int n_tasks, float alpha, unsigned int *data, unsigned int *histo, int l_mem_size #ifdef CUDA_8_0 , int* worklist #endif ); ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/cuda-setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include // Params --------------------------------------------------------------------- struct Params { int device; int n_gpu_threads; int n_gpu_blocks; int n_threads; int n_warmup; int n_reps; float alpha; int in_size; int n_bins; Params(int argc, char **argv) { device = 0; n_gpu_threads = 256; n_gpu_blocks = 16; n_threads = 4; n_warmup = 5; n_reps = 50; alpha = 0.2; in_size = 1536 * 1024 * 640; n_bins = 256; int opt; while((opt = getopt(argc, argv, "hd:i:g:t:w:r:a:n:b:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': device = atoi(optarg); break; case 'i': n_gpu_threads = atoi(optarg); break; case 'g': n_gpu_blocks = atoi(optarg); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'a': alpha = atof(optarg); break; case 'n': in_size = atoi(optarg); break; case 'b': n_bins = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } if(alpha == 0.0) { assert(n_gpu_threads > 0 && "Invalid # of device threads!"); assert(n_gpu_blocks > 0 && "Invalid # of device blocks!"); } else if(alpha == 1.0) { assert(n_threads > 0 && "Invalid # of host threads!"); } else if(alpha > 0.0 && alpha < 1.0) { assert(n_gpu_threads > 0 && "Invalid # of device threads!"); assert(n_gpu_blocks > 0 && "Invalid # of device blocks!"); assert(n_threads > 0 && "Invalid # of host threads!"); } else { #ifdef CUDA_8_0 assert((n_gpu_threads > 0 && n_gpu_blocks > 0 || n_threads > 0) && "Invalid # of host + device workers!"); #else assert(0 && "Illegal value for -a"); #endif } } void usage() { fprintf(stderr, "\nUsage: ./hsti [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d CUDA device ID (default=0)" "\n -i # of device threads per block (default=256)" "\n -g # of device blocks (default=16)" "\n -t # of host threads (default=4)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n -a fraction of input elements to process on host (default=0.2)" #ifdef CUDA_8_0 "\n NOTE: Dynamic partitioning used when is not between 0.0 and 1.0" #else "\n NOTE: must be between 0.0 and 1.0" #endif "\n" "\nBenchmark-specific options:" "\n -n input size (default=1572864, i.e., 1536x1024)" "\n -b # of bins in histogram (default=256)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(unsigned int *input, const Params &p) { char dctFileName[100]; FILE *File = NULL; // Open input file unsigned short temp; sprintf(dctFileName, "./input/image_VanHateren.iml"); if((File = fopen(dctFileName, "rb")) != NULL) { for(int y = 0; y < p.in_size; y++) { int fr = fread(&temp, sizeof(unsigned short), 1, File); input[y] = (unsigned int)ByteSwap16(temp); if(input[y] >= 4096) input[y] = 4095; } fclose(File); } else { printf("%s does not exist\n", dctFileName); exit(1); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { Params p(argc, argv); CUDASetup setcuda(p.device); Timer timer; cudaError_t cudaStatus; // Allocate buffers timer.start("Allocation"); int n_tasks = divceil(p.in_size, p.n_gpu_threads); #ifdef CUDA_8_0 unsigned int *h_in; cudaStatus = cudaMallocManaged(&h_in, p.in_size * sizeof(unsigned int)); std::atomic_uint *h_histo; cudaStatus = cudaMallocManaged(&h_histo, p.n_bins * sizeof(std::atomic_uint)); unsigned int * d_in = h_in; std::atomic_uint *d_histo = h_histo; std::atomic_int * worklist; cudaStatus = cudaMallocManaged(&worklist, sizeof(std::atomic_int)); #else unsigned int * h_in = (unsigned int *)malloc(p.in_size * sizeof(unsigned int)); std::atomic_uint *h_histo = (std::atomic_uint *)malloc(p.n_bins * sizeof(std::atomic_uint)); unsigned int * h_histo_merge = (unsigned int *)malloc(p.n_bins * sizeof(unsigned int)); unsigned int * d_in; cudaStatus = cudaMalloc((void**)&d_in, p.in_size * sizeof(unsigned int)); unsigned int * d_histo; cudaStatus = cudaMalloc((void**)&d_histo, p.n_bins * sizeof(unsigned int)); ALLOC_ERR(h_in, h_histo, h_histo_merge); #endif CUDA_ERR(); cudaDeviceSynchronize(); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); const int max_gpu_threads = setcuda.max_gpu_threads(); read_input(h_in, p); #ifdef CUDA_8_0 for(int i = 0; i < p.n_bins; i++) { h_histo[i].store(0); } #else memset(h_histo, 0, p.n_bins * sizeof(unsigned int)); #endif cudaDeviceSynchronize(); timer.stop("Initialization"); timer.print("Initialization", 1); #ifndef CUDA_8_0 // Copy to device timer.start("Copy To Device"); cudaStatus = cudaMemcpy(d_in, h_in, p.in_size * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_histo, h_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaDeviceSynchronize(); CUDA_ERR(); timer.stop("Copy To Device"); timer.print("Copy To Device", 1); #endif // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset #ifdef CUDA_8_0 if(p.alpha < 0.0 || p.alpha > 1.0) { // Dynamic partitioning worklist[0].store(0); } for(int i = 0; i < p.n_bins; i++) { h_histo[i].store(0); } #else memset(h_histo, 0, p.n_bins * sizeof(unsigned int)); cudaStatus = cudaMemcpy(d_histo, h_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyHostToDevice); cudaDeviceSynchronize(); CUDA_ERR(); #endif if(rep >= p.n_warmup) timer.start("Kernel"); p.n_gpu_blocks = p.in_size / p.n_gpu_threads; // Launch GPU threads // Kernel launch if(p.n_gpu_blocks > 0) { assert(p.n_gpu_threads <= max_gpu_threads && "The runtime block size is greater than the maximum runtime block size that can be used on this device"); cudaStatus = call_Histogram_kernel(p.n_gpu_blocks, p.n_gpu_threads, p.in_size, p.n_bins, n_tasks, p.alpha, d_in, (unsigned int*)d_histo, p.n_bins * sizeof(unsigned int) #ifdef CUDA_8_0 + sizeof(int), (int*)worklist #endif ); CUDA_ERR(); } // Launch CPU threads std::thread main_thread(run_cpu_threads, h_histo, h_in, p.in_size, p.n_bins, p.n_threads, p.n_gpu_threads, n_tasks, p.alpha #ifdef CUDA_8_0 , worklist #endif ); cudaDeviceSynchronize(); main_thread.join(); if(rep >= p.n_warmup) timer.stop("Kernel"); } timer.print("Kernel", p.n_reps); #ifndef CUDA_8_0 // Copy back timer.start("Copy Back and Merge"); cudaStatus = cudaMemcpy(h_histo_merge, d_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyDeviceToHost); CUDA_ERR(); cudaDeviceSynchronize(); for(unsigned int i = 0; i < p.n_bins; ++i) { h_histo_merge[i] += (unsigned int)h_histo[i]; } timer.stop("Copy Back and Merge"); timer.print("Copy Back and Merge", 1); #endif // Verify answer #ifdef CUDA_8_0 verify((unsigned int *)h_histo, h_in, p.in_size, p.n_bins); #else verify((unsigned int *)h_histo_merge, h_in, p.in_size, p.n_bins); #endif // Free memory timer.start("Deallocation"); #ifdef CUDA_8_0 cudaStatus = cudaFree(h_in); cudaStatus = cudaFree(h_histo); cudaStatus = cudaFree(worklist); #else free(h_in); free(h_histo); free(h_histo_merge); cudaStatus = cudaFree(d_in); cudaStatus = cudaFree(d_histo); #endif CUDA_ERR(); cudaDeviceSynchronize(); timer.stop("Deallocation"); timer.print("Deallocation", 1); // Release timers timer.release("Allocation"); timer.release("Initialization"); timer.release("Copy To Device"); timer.release("Kernel"); timer.release("Copy Back and Merge"); timer.release("Deallocation"); printf("Test Passed\n"); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/support/cuda-setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) #define CUDA_ERR() \ if(cudaStatus != cudaSuccess) { \ fprintf(stderr, "CUDA error: %s\n at %s, %d\n", cudaGetErrorString(cudaStatus), __FILE__, __LINE__); \ exit(-1); \ } struct CUDASetup { cudaDeviceProp device_prop; CUDASetup(int device) { cudaError_t cudaStatus; cudaStatus = cudaSetDevice(device); CUDA_ERR(); cudaStatus = cudaGetDeviceProperties(&device_prop, device); CUDA_ERR(); fprintf(stderr, "%s\t", device_prop.name); } int max_gpu_threads() { return device_prop.maxThreadsPerBlock; } }; ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/support/partitioner.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _PARTITIONER_H_ #define _PARTITIONER_H_ #ifndef _CUDA_COMPILER_ #include #endif #if !defined(_CUDA_COMPILER_) && defined(CUDA_8_0) #include #endif // Partitioner definition ----------------------------------------------------- typedef struct Partitioner { int n_tasks; int cut; int current; #ifndef _CUDA_COMPILER_ int thread_id; int n_threads; #endif #ifdef CUDA_8_0 // CUDA 8.0 support for dynamic partitioning int strategy; #ifdef _CUDA_COMPILER_ int *worklist; int *tmp; #else std::atomic_int *worklist; #endif #endif } Partitioner; // Partitioning strategies #define STATIC_PARTITIONING 0 #define DYNAMIC_PARTITIONING 1 // Create a partitioner ------------------------------------------------------- #ifdef _CUDA_COMPILER_ __device__ #endif inline Partitioner partitioner_create(int n_tasks, float alpha #ifndef _CUDA_COMPILER_ , int thread_id, int n_threads #endif #ifdef CUDA_8_0 #ifdef _CUDA_COMPILER_ , int *worklist , int *tmp #else , std::atomic_int *worklist #endif #endif ) { Partitioner p; p.n_tasks = n_tasks; #ifndef _CUDA_COMPILER_ p.thread_id = thread_id; p.n_threads = n_threads; #endif if(alpha >= 0.0 && alpha <= 1.0) { p.cut = p.n_tasks * alpha; #ifdef CUDA_8_0 p.strategy = STATIC_PARTITIONING; #endif } else { #ifdef CUDA_8_0 p.strategy = DYNAMIC_PARTITIONING; p.worklist = worklist; #ifdef _CUDA_COMPILER_ p.tmp = tmp; #endif #endif } return p; } // Partitioner iterators: first() --------------------------------------------- #ifndef _CUDA_COMPILER_ inline int cpu_first(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { p->current = p->worklist->fetch_add(1); } else #endif { p->current = p->thread_id; } return p->current; } #else __device__ inline int gpu_first(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { if(threadIdx.y == 0 && threadIdx.x == 0) { p->tmp[0] = atomicAdd_system(p->worklist, 1); } __syncthreads(); p->current = p->tmp[0]; } else #endif { p->current = p->cut + blockIdx.x; } return p->current; } #endif // Partitioner iterators: more() ---------------------------------------------- #ifndef _CUDA_COMPILER_ inline bool cpu_more(const Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { return (p->current < p->n_tasks); } else #endif { return (p->current < p->cut); } } #else __device__ inline bool gpu_more(const Partitioner *p) { return (p->current < p->n_tasks); } #endif // Partitioner iterators: next() ---------------------------------------------- #ifndef _CUDA_COMPILER_ inline int cpu_next(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { p->current = p->worklist->fetch_add(1); } else #endif { p->current = p->current + p->n_threads; } return p->current; } #else __device__ inline int gpu_next(Partitioner *p) { #ifdef CUDA_8_0 if(p->strategy == DYNAMIC_PARTITIONING) { if(threadIdx.y == 0 && threadIdx.x == 0) { p->tmp[0] = atomicAdd_system(p->worklist, 1); } __syncthreads(); p->current = p->tmp[0]; } else #endif { p->current = p->current + gridDim.x; } return p->current; } #endif #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { cudaEventCreate(&startTime[name]); cudaEventCreate(&stopTime[name]); time[name] = 0.0; } cudaEventRecord(startTime[name], 0); } void stop(string name) { cudaEventRecord(stopTime[name],0); cudaEventSynchronize(stopTime[name]); float part_time = 0.0; cudaEventElapsedTime(&part_time, startTime[name], stopTime[name]); time[name] += part_time; } void print(string name, unsigned int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / REP); } void release(string name){ cudaEventDestroy(startTime[name]); cudaEventDestroy(stopTime[name]); } }; ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/baselines/gpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include #include inline int compare_output(unsigned int *outp, unsigned int *outpCPU, int bins) { for(int i = 0; i < bins; i++) { if(outp[i] != outpCPU[i]) { printf("Test failed\n"); exit(EXIT_FAILURE); } } return 0; } // Sequential implementation for comparison purposes inline void HistogramCPU(unsigned int *histo, unsigned int *data, int size, int bins) { for(int i = 0; i < size; i++) { // Read pixel unsigned int d = ((data[i] * bins) >> 12); // Vote in histogram histo[d]++; } } inline void verify(unsigned int *histo, unsigned int *input, int size, int bins) { unsigned int *gold = (unsigned int *)malloc(bins * sizeof(unsigned int)); memset(gold, 0, bins * sizeof(unsigned int)); HistogramCPU(gold, input, size, bins); compare_output(histo, gold, bins); free(gold); } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/HST-S/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(HST-S_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/dpu/task.c ================================================ /* * Histogram (HST-S) with multiple tasklets * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // Array for communication between adjacent tasklets uint32_t* message[NR_TASKLETS]; // DPU histogram uint32_t* histo_dpu; // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Histogram in each tasklet void __attribute__ ((noinline)) histogram(uint32_t* histo, uint32_t bins, T *input, unsigned int l_size){ for(unsigned int j = 0; j < l_size; j++) { T d = input[j]; histo[(d * bins) >> DEPTH] += 1; } } extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes uint32_t bins = DPU_INPUT_ARGUMENTS.bins; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_histo = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local histogram uint32_t *histo = (uint32_t *) mem_alloc(bins * sizeof(uint32_t)); // Initialize local histogram for(unsigned int i = 0; i < bins; i++){ histo[i] = 0; } // Compute histogram for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Histogram in each tasklet histogram(histo, bins, cache_A, l_size_bytes >> DIV); } message[tasklet_id] = histo; // Barrier barrier_wait(&my_barrier); uint32_t *histo_dpu = message[0]; for (unsigned int i = tasklet_id; i < bins; i += NR_TASKLETS){ uint32_t b = 0; for (unsigned int j = 0; j < NR_TASKLETS; j++){ b += *(message[j] + i); } histo_dpu[i] = b; } // Barrier barrier_wait(&my_barrier); // Write dpu histogram to current MRAM block if(tasklet_id == 0){ if(bins * sizeof(uint32_t) <= 2048) mram_write(histo_dpu, (__mram_ptr void*)(mram_base_addr_histo), bins * sizeof(uint32_t)); else for(unsigned int offset = 0; offset < ((bins * sizeof(uint32_t)) >> 11); offset++){ mram_write(histo_dpu + (offset << 9), (__mram_ptr void*)(mram_base_addr_histo + (offset << 11)), 2048); } } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define DEPTH 12 struct dpu_arguments_t { int size; int transfer_size; int bins; int kernel; }; void read_input(int* A, int input_size) { for (int i = 0; i < input_size; i++) { A[i] = i % 4096; } } void histogram_host(int* histo, int* A, int bins, int nr_elements, int exp, int nr_of_dpus) { if(!exp){ for (int i = 0; i < nr_of_dpus; i++) { for (int j = 0; j < nr_elements; j++) { int d = A[j]; histo[i * bins + ((d * bins) >> DEPTH)] += 1; } } } else{ for (int j = 0; j < nr_elements; j++) { int d = A[j]; histo[(d * bins) >> DEPTH] += 1; } } } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { int* A; int* histo_host; int* histo; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int input_size = DATA_PREP_PARAMS; int input_size_8bytes = ((input_size * sizeof(int)) % 8) != 0 ? roundup(input_size, 8) : input_size; int input_size_dpu = divceil(input_size, nr_of_dpus); int input_size_dpu_8bytes = ((input_size_dpu * sizeof(int)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; int bins = 256; A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); int *bufferA = A; histo_host = malloc(bins * sizeof(int)); histo = malloc(nr_of_dpus * bins * sizeof(int)); read_input(A, input_size); for (int i = 0; i < bins; i++) { histo_host[i] = 0; } for (int i = 0; i < nr_of_dpus * bins; i++) { histo[i] = 0; } histogram_host(histo_host, A, bins, input_size, 1, nr_of_dpus); int kernel = 0; struct dpu_arguments_t* input_arguments = malloc(NUM_DPUS * sizeof(struct dpu_arguments_t)); for(int i=0; i profile/HSTS_${b}_tl${k}_dpu${i}.txt wait make clean wait done done done ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #define REGS (BLOCK_SIZE >> 2) // 32 bits // Pixel depth #define DEPTH 12 #define ByteSwap16(n) (((((unsigned int)n) << 8) & 0xFF00) | ((((unsigned int)n) >> 8) & 0x00FF)) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; uint32_t transfer_size; uint32_t bins; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; unsigned int bins; int n_warmup; int n_reps; const char *file_name; int exp; int dpu_s; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1, 2) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=1536*1024 elements)" "\n -b histogram size (default=256 bins)" "\n -f input image file (default=../input/image_VanHateren.iml)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1536 * 1024; p.bins = 256; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.file_name = "./input/image_VanHateren.iml"; p.dpu_s = 64; int opt; while((opt = getopt(argc, argv, "hi:b:w:e:f:x:z:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'b': p.bins = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'f': p.file_name = optarg; break; case 'x': p.exp = atoi(optarg); break; case 'z': p.dpu_s = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/HST-S/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -m 1024 -n 1024 ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_10_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_11_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_12_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_13_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_14_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_15_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_16 ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_16_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_17_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_18_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_19_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_1_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_20_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_21_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_22_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_23_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_24_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_2_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_3_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_4_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_5_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_6_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_7_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_8_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/_NR_TASKLETS_9_BL_10.conf ================================================ ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/cpu/Makefile ================================================ all: gcc mlp_openmp.c -o mlp_openmp -fopenmp -std=c99 run: ./mlp_openmp ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/cpu/README ================================================ Multilayer Perceptron (MLP) Compilation instructions make Execution instructions ./mlp_openmp ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/cpu/mlp_openmp.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include "../../support/timer.h" #include "../../support/common.h" T** A; T* B; T* C; // Create input arrays static void init_data(T** A, T* B, unsigned int m_size, unsigned int n_size){ for (unsigned int l = 0; l < NUM_LAYERS; l++) for (unsigned int i = 0; i < m_size * n_size; i++){ if(i % 100 < 98){ A[l][i] = 0; }else{ A[l][i] = (l+i) % 2; } } for (unsigned int i = 0; i < n_size; i++){ if(i % 50 < 48){ B[i] = 0; } else{ B[i] = i % 2; } } } // Compute output in the host static void mlp_host(T* C, T** A, T* B, unsigned int m_size, unsigned int n_size) { for (unsigned int nl = 0; nl < NUM_LAYERS; nl++){ for (unsigned int m = 0; m < m_size; m++){ C[m] = 0; } #pragma omp parallel for for (unsigned int m = 0; m < m_size; m++){ for (unsigned int n = 0; n < n_size; n++){ C[m] += A[nl][m * n_size + n] * B[n]; } C[m] = max(0, C[m]); } for (unsigned int n = 0; n < n_size; n++){ B[n] = C[n]; } } } static uint64_t mlp_host_sum(uint64_t n_size, uint64_t m_size) { uint64_t sum = 0; for (uint64_t m = 0; m < n_size; m++){ sum += B[m]; } return sum; } // Params --------------------------------------------------------------------- typedef struct Params { char* dpu_type; int nr_of_ranks; int input_size_n; int input_size_m; int n_warmup; int n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d DPU type (default=fsim)" "\n -r # of ranks (default=2)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.dpu_type = "fsim"; p.nr_of_ranks = 1; p.input_size_n = 1 << 9; p.input_size_m = 1 << 9; p.n_warmup = 2; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hd:r:i:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': p.dpu_type = optarg; break; case 'r': p.nr_of_ranks = atoi(optarg); break; case 'n': p.input_size_n = atoi(optarg); break; case 'm': p.input_size_m = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.nr_of_ranks > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); uint64_t n_size = 8192; uint64_t m_size = 20480; Timer timer; A = malloc(NUM_LAYERS * sizeof(T*)); for(int l = 0; l < NUM_LAYERS; l++) A[l] = malloc(n_size*m_size*sizeof(unsigned int)); B = malloc(m_size*sizeof(unsigned int)); C = malloc(m_size*sizeof(unsigned int)); // Create an input file with arbitrary data. init_data(A, B, m_size, n_size); start(&timer, 0, 1); mlp_host(C, A, B, n_size, m_size); stop(&timer, 0); uint32_t sum = mlp_host_sum(n_size, m_size); printf("Kernel "); print(&timer, 0, 1); printf("\n"); printf("SUM = %d \n", sum); for(int l = 0; l < NUM_LAYERS; l++) free(A[l]); free(A); free(B); free(C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc mlp.cu -I/usr/local/cuda/include -lm -o mlp clean: rm mlp ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/gpu/README ================================================ Multilayer Perceptron (MLP) Compilation instructions make Execution instructions ./mlp ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/baselines/gpu/mlp.cu ================================================ #include #include #include #include #include "../../support/common.h" #define THREAD 128 __global__ void gemv(int m, int n, T *adim, T *b, T *d_ans); void cgemv(int m, int n, T *adim, T *b, T *d_ans); double gettime() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1.0e-6; } int main(int argc, char **argv) { /* for CPU */ int i, j; T **bdim; T *c, *ans, *h_ans, *h_c; int n = 8192; int m = 20480; bdim = (T**) malloc(NUM_LAYERS * sizeof(T*)); for(int l = 0; l < NUM_LAYERS; l++) bdim[l] = (T*)malloc(sizeof(T)*m*n); c = (T*)malloc(sizeof(T) *n); h_c = (T*)malloc(sizeof(T) *n); ans = (T*)malloc(sizeof(T) *m); h_ans = (T*)malloc(sizeof(T) *m); /* for GPU */ T *d_bdim; T *d_c, *d_ans; cudaMalloc((void **)&d_bdim, sizeof(T)*m*n); cudaMalloc((void **)&d_c, sizeof(T)*n); cudaMalloc((void **)&d_ans, sizeof(T)*m); for(i = 0; i < n; i++) { if(i % 50 < 48) { c[i] = 0; h_c[i] = 0; } else { c[i] = i % 2; h_c[i] = i % 2; } } for(int l = 0; l < NUM_LAYERS; l++) for(i = 0; i < n; i++) { for(j = 0; j < m; j++){ if(j % 100 < 98) { bdim[l][i*m+j] = 0; } else { bdim[l][i*m+j] = (l + i) % 2; } } } for(j = 0; j < m; j++){ ans[j] = 0; h_ans[j] = 0; } // Computation on the host for verification T* vector = c; T* output = ans; T* matrix; int mm = m; int nn = n; for(int l = 0; l < NUM_LAYERS; l++){ matrix = bdim[l]; cgemv(mm, nn, matrix, vector, output); vector = output; h_ans = output; mm = n; nn = m; } // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; cudaMemcpy(d_ans, h_ans, sizeof(T)*m, cudaMemcpyHostToDevice); cudaMemcpy(d_c, h_c, sizeof(T)*n, cudaMemcpyHostToDevice); vector = d_c; output = d_ans; mm = m; nn = n; for(int l = 0; l < NUM_LAYERS; l++){ cudaMemcpy(d_bdim, bdim[l], sizeof(T)*m*n, cudaMemcpyHostToDevice); matrix = d_bdim; // Start timer cudaEventRecord( start, 0 ); gemv<<>>(mm, nn, matrix, vector, output); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time2, start, stop ); time1 += time2; vector = output; d_ans = output; mm = n; nn = m; } cudaMemcpy(h_ans, d_ans, sizeof(T)*m, cudaMemcpyDeviceToHost); cudaMemcpy(h_c, d_c, sizeof(T)*n, cudaMemcpyDeviceToHost); for(i = 0; i < m; i++) { if(ans[i] != h_ans[i]) printf("ERROR in Ans %d -> %d -- %d\n", i, ans[i], h_ans[i]); } for(i = 0; i < n; i++) { if(c[i] != h_c[i]) printf("ERROR in C %d -> %d -- %d\n", i, c[i], h_c[i]); } printf("Execution time = %f ms\n", time1); for(int l = 0; l < NUM_LAYERS; l++) free(bdim[l]); free(bdim); free(c); free(ans); free(h_c); cudaFree(d_bdim); cudaFree(d_c); cudaFree(d_ans); cudaEventDestroy(start); cudaEventDestroy(stop); return 0; } __global__ void gemv(int m, int n, T* adim, T* b, T* d_ans) { int i; int div = n/THREAD; __shared__ T tmp[THREAD]; tmp[threadIdx.x] = 0.0; for(i = 0; i < div; i++){ tmp[threadIdx.x] += adim[blockIdx.x*n+i*THREAD+threadIdx.x] * b[i * THREAD + threadIdx.x]; } if(threadIdx.x < m%THREAD) tmp[threadIdx.x] += adim[blockIdx.x*n+THREAD*div+threadIdx.x] * b[THREAD * div + threadIdx.x]; __syncthreads(); for(i = THREAD / 2; i > 31; i = i / 2) { if(threadIdx.x < i) tmp[threadIdx.x] += tmp[threadIdx.x + i]; __syncthreads(); } if(threadIdx.x < 16) { tmp[threadIdx.x] += tmp[threadIdx.x + 16]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 8]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 4]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 2]; __syncthreads(); tmp[threadIdx.x] += tmp[threadIdx.x + 1]; __syncthreads(); } if(threadIdx.x == 0) d_ans[blockIdx.x] = max(0, tmp[0]); } void cgemv(int m, int n, T *adim, T *b, T *d_ans) { int i, j; for(i = 0; i < m; i++){ for(j = 0; j < n; j++) d_ans[i] += adim[i*n+j] * b[j]; d_ans[i] = max(0, d_ans[i]); } } ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/MLP/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(MLP_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/dpu/task.c ================================================ /* * Matrix vector multiplication with multiple tasklet * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // GEMV void __attribute__ ((noinline)) gemv(T *bufferC, T *bufferA, T *bufferB, int pos) { for (unsigned int i = 0; i < BLOCK_SIZE / sizeof(T); i++) { bufferC[pos] += bufferA[i] * bufferB[i]; } return; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // main int main() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); int32_t n_size = DPU_INPUT_ARGUMENTS.n_size; int32_t n_size_pad = DPU_INPUT_ARGUMENTS.n_size_pad; uint32_t nr_rows = DPU_INPUT_ARGUMENTS.nr_rows; uint32_t max_rows = DPU_INPUT_ARGUMENTS.max_rows; unsigned int nrows = nr_rows; unsigned int rows_per_tasklet; unsigned int start_row; unsigned int chunks = nrows / (NR_TASKLETS + NR_TASKLETS); unsigned int dbl_chunks = chunks + chunks; rows_per_tasklet = dbl_chunks; unsigned int rest_rows = nrows % (NR_TASKLETS + NR_TASKLETS); if ((tasklet_id + tasklet_id) < rest_rows) rows_per_tasklet += 2; if (rest_rows > 0) { if ((tasklet_id + tasklet_id) >= rest_rows) { unsigned int hlf_rest_rows = rest_rows >> 1; if ((rest_rows & 1) == 1) start_row = (hlf_rest_rows + 1) * (dbl_chunks + 2) + (tasklet_id - 1 - hlf_rest_rows) * dbl_chunks; else start_row = (hlf_rest_rows) * (dbl_chunks + 2) + (tasklet_id - hlf_rest_rows) * dbl_chunks; } else start_row = tasklet_id * (dbl_chunks + 2); } else { start_row = tasklet_id * (dbl_chunks); } // Address of the current row in MRAM uint32_t mram_base_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + start_row * n_size * sizeof(T)); uint32_t mram_base_addr_B = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T)); uint32_t mram_base_addr_C = (uint32_t) (DPU_MRAM_HEAP_POINTER + max_rows * n_size_pad * sizeof(T) + n_size_pad * sizeof(T) + start_row * sizeof(T)); uint32_t mram_temp_addr_A = mram_base_addr_A; uint32_t mram_temp_addr_B = mram_base_addr_B; // Inititalize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE + 8); T *cache_A_aux = (T *) mem_alloc(8); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); T *cache_C = (T *) mem_alloc(8); int offset = 0; // Iterate over nr_rows for (unsigned int i = start_row; i < start_row + rows_per_tasklet; i += 2) { mram_temp_addr_A = (uint32_t) (DPU_MRAM_HEAP_POINTER + i * n_size * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; cache_C[0] = 0; cache_C[1] = 0; for(unsigned int pos = 0; pos < 2 && i + pos < nr_rows; pos++){ int n = 0, j; for (n = 0; n < (int32_t) (n_size - (BLOCK_SIZE/sizeof(T))); n += (BLOCK_SIZE / sizeof(T))) { mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) - 1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } // Compute GEMV gemv(cache_C, cache_A, cache_B, pos); // Update memory addresses mram_temp_addr_A += BLOCK_SIZE; mram_temp_addr_B += BLOCK_SIZE; } mram_read((__mram_ptr void const*) (mram_temp_addr_A), cache_A, BLOCK_SIZE); if(offset) { for(unsigned int off = 0; off < (BLOCK_SIZE / sizeof(T)) -1; off++) { cache_A[off] = cache_A[off + 1]; } mram_read((__mram_ptr void const*) (mram_temp_addr_A + BLOCK_SIZE ), cache_A_aux, 8); cache_A[BLOCK_SIZE / sizeof(T) - 1] = cache_A_aux[0]; } mram_read((__mram_ptr void const*) (mram_temp_addr_B), cache_B, BLOCK_SIZE); for (j = 0; j < (int) (n_size - n); j++) { // Compute GEMV if(j >= (int)(BLOCK_SIZE / sizeof(T))){ printf("error\n"); break; } cache_C[pos] += cache_A[j] * cache_B[j]; } mram_temp_addr_A += (BLOCK_SIZE - ((BLOCK_SIZE / sizeof(T)) - (n_size - n)) * sizeof(T)); mram_temp_addr_B = mram_base_addr_B; if(mram_temp_addr_A % 8 != 0) { offset = 1; } else { offset = 0; } } // Write cache to current MRAM block mram_write(cache_C, (__mram_ptr void *) (mram_base_addr_C), 8); // Update memory address mram_base_addr_C += 2 * sizeof(T); } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define NUM_LAYERS 3 struct dpu_arguments_t { int n_size; int n_size_pad; int nr_rows; int max_rows; }; struct dpu_info_t { int rows_per_dpu; int rows_per_dpu_pad; int prev_rows_dpu; }; void init_data(int* A, int* B, int* B_host, int m_size, int n_size) { for (int l = 0; l < NUM_LAYERS; l++) { for (int i = 0; i < m_size * n_size; i++){ if(i % 100 < 98){ A[l * m_size * n_size + i] = 0; }else{ A[l * m_size * n_size + i] = (l+i) % 2; } } } for (int i = 0; i < n_size; i++){ if(i % 50 < 48){ B[i] = 0; } else{ B[i] = i % 2; } B_host[i] = B[i]; } } void mlp_host(int* C, int* A, int* B, int m_size, int n_size) { for (int nl = 0; nl < NUM_LAYERS; nl++){ for (int m = 0; m < m_size; m++){ C[m] = 0; } for (int m = 0; m < m_size; m++){ for (int n = 0; n < n_size; n++){ C[m] += A[nl * m_size + n_size + m * n_size + n] * B[n]; } if (C[m] < 0) { C[m] = 0; } } for (int n = 0; n < n_size; n++){ B[n] = C[n]; } } } int main() { int* A; int* B; int* B_host; int* B_tmp; int* C; int* C_dpu; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NR_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int i; int l; int m_size = DATA_PREP_PARAMS; int n_size = DATA_PREP_PARAMS; struct dpu_info_t* dpu_info = malloc(nr_of_dpus * sizeof(struct dpu_info_t)); struct dpu_arguments_t *input_args = malloc(nr_of_dpus * sizeof(struct dpu_arguments_t)); int max_rows_per_dpu = 0; int n_size_pad = n_size; if(n_size % 2 == 1){ n_size_pad++; } DPU_FOREACH(dpu_set, dpu, i) { int rows_per_dpu; int prev_rows_dpu = 0; int chunks = m_size / nr_of_dpus; rows_per_dpu = chunks; int rest_rows = m_size % nr_of_dpus; if (i < rest_rows) { rows_per_dpu++; } if (rest_rows > 0) { if (i >= rest_rows) { prev_rows_dpu = rest_rows * (chunks + 1) + (i - rest_rows) * chunks; } else { prev_rows_dpu = i * (chunks + 1); } } else { prev_rows_dpu = i * chunks; } int rows_per_dpu_pad = rows_per_dpu; if (rows_per_dpu_pad % 2 == 1) { rows_per_dpu_pad++; } if (rows_per_dpu_pad > max_rows_per_dpu) { max_rows_per_dpu = rows_per_dpu_pad; } dpu_info[i].rows_per_dpu = rows_per_dpu; dpu_info[i].rows_per_dpu_pad = rows_per_dpu_pad; dpu_info[i].prev_rows_dpu = prev_rows_dpu; input_args[i].n_size = n_size; input_args[i].n_size_pad = n_size_pad; input_args[i].nr_rows = rows_per_dpu; } A = malloc(NUM_LAYERS * max_rows_per_dpu * nr_of_dpus * n_size_pad * sizeof(int)); B = malloc(n_size * sizeof(int)); B_host = malloc(n_size * sizeof(int)); C = malloc(m_size * sizeof(int)); C_dpu = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(int)); B_tmp = malloc(max_rows_per_dpu * nr_of_dpus * sizeof(int)); init_data(A, B, B_host, m_size, n_size); mlp_host(C, A, B_host, m_size, n_size); DPU_FOREACH(dpu_set, dpu, i) { input_args[i].max_rows = max_rows_per_dpu; dpu_prepare_xfer(dpu, &input_args[i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &A[dpu_info[i].prev_rows_dpu * n_size]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(int), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, B); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) , n_size_pad * sizeof(int), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); for(int lay = 1; lay < NUM_LAYERS; lay++){ i = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &C_dpu[i * max_rows_per_dpu]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) + n_size_pad * sizeof(int), max_rows_per_dpu * sizeof(int), DPU_XFER_DEFAULT); for (int n = 0; n < nr_of_dpus; n++) { for (int j = 0; j < dpu_info[n].rows_per_dpu; j++) { B_tmp[i] = C_dpu[n * max_rows_per_dpu + j]; i++; } } DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, B_tmp); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) , n_size_pad * sizeof(int), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &A[lay * max_rows_per_dpu * nr_of_dpus * n_size_pad + dpu_info[i].prev_rows_dpu * n_size]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, max_rows_per_dpu * n_size_pad * sizeof(int), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); } DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &C_dpu[i * max_rows_per_dpu]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, max_rows_per_dpu * n_size_pad * sizeof(int) + n_size_pad * sizeof(int), max_rows_per_dpu * sizeof(int), DPU_XFER_DEFAULT); int status = 1; i = 0; for (int n = 0; n < nr_of_dpus; n++) { for (int j = 0; j < dpu_info[n].rows_per_dpu; j++) { if(C[i] != C_dpu[n * max_rows_per_dpu + j]) { status = 0; } i++; } } assert(status); free(A); free(B); free(C); free(C_dpu); dpu_free(dpu_set); return status ? 0 : -1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t n_size; uint32_t n_size_pad; uint32_t nr_rows; uint32_t max_rows; } dpu_arguments_t; // Specific information for each DPU struct dpu_info_t { uint32_t rows_per_dpu; uint32_t rows_per_dpu_pad; uint32_t prev_rows_dpu; }; struct dpu_info_t *dpu_info; #define NUM_LAYERS 3 #define max(x, y) (x > y ? x : y) #define min(x, y) (x < y ? x : y) // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T int32_t #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int m_size; unsigned int n_size; unsigned int n_warmup; unsigned int n_reps; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -m m_size (default=2048 elements)" "\n -n n_size (default=2048 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.m_size = 163840; p.n_size = 4096; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hm:n:w:e:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'm': p.m_size = atoi(optarg); break; case 'n': p.n_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/MLP/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[5]; struct timeval stopTime[5]; double time[5]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); //printf("Time (ms): %f\t",((timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + // (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec)) / 1000); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 VERSION ?= SINGLE SYNC ?= HAND TYPE ?= INT64 ENERGY ?= 0 PERF ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_VERSION_$(4)_SYNC_$(5)_TYPE_$(6).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${VERSION},${SYNC},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DENERGY=${ENERGY} -DPERF=${PERF} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DPERF=${PERF} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -w 0 -e 1 -i 6553600 -x 1 ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/cpu/Makefile ================================================ all: g++ -O2 app_baseline.cpp -fopenmp -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_CPP -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP -lgomp -I/usr/local/cuda-8.0/include -lm -o red -D${TYPE} clean: rm red ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/cpu/README ================================================ Reduction (RED) Compilation instructions TYPE=UINT64 make Execution instructions ./red -i 1048576000 -t 4 ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/cpu/app_baseline.cpp ================================================ /* * JGL@SAFARI */ /** * CPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static T reduction_host(T* A, unsigned int nr_elements) { T count = 0; for (unsigned int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=2M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2 << 20; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 1; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; assert(input_size % (p.n_threads) == 0 && "Input size!"); // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; T count = 0; T count_host = 0; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::omp::vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); count_host = reduction_host(A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); thrust::omp::vector d_input(input_size); memcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T)); omp_set_num_threads(p.n_threads); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); count = thrust::reduce(thrust::omp::par, d_input.begin(), d_input.end()); if(rep >= p.n_warmup) stop(&timer, 1); h_output = d_input; } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel "); print(&timer, 1, p.n_reps); // Check output bool status = true; if(count_host != count){ status = false; printf("%lu -- %lu\n", count, count_host); } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc app_baseline.cu -I/usr/local/cuda/include -lm -o red -D${TYPE} clean: rm red ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/gpu/README ================================================ Reduction (RED) Compilation instructions TYPE=UINT64 make Execution instructions ./red -i 1048576000 ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/baselines/gpu/app_baseline.cu ================================================ /* * JGL@SAFARI */ /** * GPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static T reduction_host(T* A, unsigned int nr_elements) { T count = 0; for (unsigned int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 160 * 6553600; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties, 0); cudaSetDevice(0); struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; T count = 0; T count_host = 0; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::host_vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); count_host = reduction_host(A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; thrust::device_vector d_input(input_size); cudaMemcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T), cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); count = thrust::reduce(d_input.begin(),d_input.end()); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); time_gpu += time1; h_output = d_input; cudaEventDestroy(start); cudaEventDestroy(stop); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel (ms):"); printf("%f\n", time_gpu / p.n_reps); // Check output bool status = true; if(count_host != count){ status = false; printf("%lu -- %lu\n", count, count_host); } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) SET(VERSION SINGLE) SET(SYNC HAND) SET(PERF 0) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/RED/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${VERSION} -D${SYNC} -D${TYPE} -DPERF=${PERF}") file(GLOB_RECURSE SRCS *.c) add_executable(RED_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/dpu/task.c ================================================ /* * Reduction with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" #include "../support/cyclecount.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; // Reduction in each tasklet T __attribute__ ((noinline)) reduction(T *input, unsigned int l_size){ T output = 0; for (unsigned int j = 0; j < l_size; j++){ output += input[j]; } return output; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap #if PERF perfcounter_config(COUNT_CYCLES, true); #endif } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; #if PERF && !PERF_SYNC result->cycles = 0; perfcounter_cycles cycles; timer_start(&cycles); // START TIMER #endif uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local count T l_count = 0; #if !PERF_SYNC // COMMENT OUT TO COMPARE SYNC PRIMITIVES (Experiment in Appendix) for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); // Reduction in each tasklet l_count += reduction(cache_A, l_size_bytes >> DIV); } #endif // Reduce local counts message[tasklet_id] = l_count; #if PERF && PERF_SYNC // TIMER FOR SYNC PRIMITIVES result->cycles = 0; perfcounter_cycles cycles; timer_start(&cycles); // START TIMER #endif #ifdef TREE // Tree-based reduction #ifdef BARRIER // Barrier barrier_wait(&my_barrier); #endif #pragma unroll for (unsigned int offset = 1; offset < NR_TASKLETS; offset <<= 1){ if((tasklet_id & (2*offset - 1)) == 0){ #ifndef BARRIER // Wait handshake_wait_for(tasklet_id + offset); #endif message[tasklet_id] += message[tasklet_id + offset]; } #ifdef BARRIER // Barrier barrier_wait(&my_barrier); #else else if ((tasklet_id & (offset - 1)) == 0){ // Ensure that wait and notify are in pair // Notify handshake_notify(); } #endif } #else // Single-thread reduction // Barrier barrier_wait(&my_barrier); if(tasklet_id == 0) #pragma unroll for (unsigned int each_tasklet = 1; each_tasklet < NR_TASKLETS; each_tasklet++){ message[0] += message[each_tasklet]; } #endif #if PERF && PERF_SYNC // TIMER FOR SYNC PRIMITIVES result->cycles = timer_stop(&cycles); // STOP TIMER #endif // Total count in this DPU if(tasklet_id == 0){ result->t_count = message[tasklet_id]; } #if PERF && !PERF_SYNC result->cycles = timer_stop(&cycles); // STOP TIMER #endif return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 struct dpu_arguments_t{ int size; int kernel; long t_count; }; struct dpu_results_t{ long cycles; long t_count; }; void read_input(long* A, int nr_elements) { for (int i = 0; i < nr_elements; i++) { A[i] = i % 100; } } long reduction_host(long* A, int nr_elements) { long count = 0; for (int i = 0; i < nr_elements; i++) { count += A[i]; } return count; } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { long* A; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int input_size = DATA_PREP_PARAMS; int input_size_8bytes = ((input_size * sizeof(long)) % 8) != 0 ? roundup(input_size, 8) : input_size; int input_size_dpu = divceil(input_size, nr_of_dpus); int input_size_dpu_8bytes = ((input_size_dpu * sizeof(long)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(long)); long *bufferA = A; long count = 0; long count_host = 0; read_input(A, input_size); count_host = reduction_host(A, input_size); count = 0; int kernel = 0; struct dpu_arguments_t* input_arguments = malloc(NUM_DPUS * sizeof(struct dpu_arguments_t)); for(int i=0; i profile/TREE_${j}_tl${k}_dpu${i}.txt #./bin/host_code -w 2 -e 10 -i 2048 > profile/TREE_${j}_tl${k}_dpu${i}.txt wait make clean wait done done done for i in 1 do for k in 1 2 4 8 16 do PERF=1 NR_DPUS=$i NR_TASKLETS=$k BL=10 VERSION=SINGLE make all wait ./bin/host_code -w 2 -e 10 -i 2097152 > profile/SINGLE_SINGLE_tl${k}_dpu${i}.txt #./bin/host_code -w 2 -e 10 -i 2048 > profile/SINGLE_SINGLE_tl${k}_dpu${i}.txt wait make clean wait done done ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; T t_count; } dpu_arguments_t; typedef struct { uint64_t cycles; T t_count; } dpu_results_t; #ifndef PERF #define PERF 0 // Use perfcounters? #endif #ifndef PERF_SYNC #define PERF_SYNC 0 // Use perfcounters to time sync primitives? #endif #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/support/cyclecount.h ================================================ #include // Timer typedef struct perfcounter_cycles{ perfcounter_t start; perfcounter_t end; perfcounter_t end2; }perfcounter_cycles; void timer_start(perfcounter_cycles *cycles){ cycles->start = perfcounter_get(); // START TIMER } uint64_t timer_stop(perfcounter_cycles *cycles){ cycles->end = perfcounter_get(); // STOP TIMER cycles->end2 = perfcounter_get(); // STOP TIMER return(((uint64_t)((uint32_t)(((cycles->end >> 4) - (cycles->start >> 4)) - ((cycles->end2 >> 4) - (cycles->end >> 4))))) << 4); } ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=6553600 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 6553600; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/RED/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 BL ?= 10 TYPE ?= INT64 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/Makefile ================================================ all: g++ -O2 app_baseline.cpp -fopenmp -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_CPP -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_OMP -lgomp -I/usr/local/cuda-8.0/include -lm -o scan -D${TYPE} clean: rm scan ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/README ================================================ Prefix sum (SCAN) Compilation instructions TYPE=UINT64 make Execution instructions ./scan -i 1258291200 -t 4 ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/cpu/app_baseline.cpp ================================================ /* * JGL@SAFARI */ /** * CPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i - 1]; } } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2 << 20; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.input_size; assert(input_size % (p.n_threads) == 0 && "Input size!"); // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::omp::vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); memcpy(thrust::raw_pointer_cast(&h_output[0]), A, input_size * sizeof(T)); omp_set_num_threads(p.n_threads); if(rep >= p.n_warmup) start(&timer, 1, rep - p.n_warmup); thrust::exclusive_scan(thrust::omp::par, h_output.begin(),h_output.end(),h_output.begin()); if(rep >= p.n_warmup) stop(&timer, 1); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel "); print(&timer, 1, p.n_reps); // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != h_output[i]){ status = false; //printf("%d: %lu -- %lu\n", i, C[i], h_output[i]); } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc app_baseline.cu -I/usr/local/cuda/include -lm -o scan -D${TYPE} clean: rm scan ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/README ================================================ Prefix sum (SCAN) Compilation instructions TYPE=UINT64 make Execution instructions ./scan -i 1258291200 ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/baselines/gpu/app_baseline.cu ================================================ /* * JGL@SAFARI */ /** * GPU code with Thrust */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../support/common.h" #include "../../support/timer.h" #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" // Pointer declaration static T* A; static T* C; static T* C2; /** * @brief creates input arrays * @param nr_elements how many elements in input arrays */ static void read_input(T* A, unsigned int nr_elements) { //srand(0); printf("nr_elements\t%u\t", nr_elements); for (unsigned int i = 0; i < nr_elements; i++) { //A[i] = (T) (rand()) % 2; A[i] = i; } } /** * @brief compute output in the host */ static void scan_host(T* C, T* A, unsigned int nr_elements) { C[0] = A[0]; for (unsigned int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i - 1]; } } // Params --------------------------------------------------------------------- typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n -t # of threads (default=8)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=640 * 3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 1258291200; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of threads!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties, 0); cudaSetDevice(0); struct Params p = input_params(argc, argv); unsigned int nr_of_dpus = 1; unsigned int i = 0; const unsigned int input_size = p.exp == 0 ? p.input_size * nr_of_dpus : p.input_size; // Input/output allocation A = (T*)malloc(input_size * sizeof(T)); C = (T*)malloc(input_size * sizeof(T)); C2 = (T*)malloc(input_size * sizeof(T)); T *bufferA = A; T *bufferC = C2; // Create an input file with arbitrary data. read_input(A, input_size); // Timer declaration Timer timer; float time_gpu = 0; thrust::host_vector h_output(input_size); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Compute output on CPU (performance comparison and verification purposes) if(rep >= p.n_warmup) start(&timer, 0, rep - p.n_warmup); scan_host(C, A, input_size); if(rep >= p.n_warmup) stop(&timer, 0); // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; thrust::device_vector d_input(input_size); cudaMemcpy(thrust::raw_pointer_cast(&d_input[0]), A, input_size * sizeof(T), cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); thrust::exclusive_scan(d_input.begin(),d_input.end(),d_input.begin()); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); time_gpu += time1; h_output = d_input; cudaEventDestroy(start); cudaEventDestroy(stop); } // Print timing results printf("CPU "); print(&timer, 0, p.n_reps); printf("Kernel (ms):"); printf("%f\n", time_gpu / p.n_reps); // Check output bool status = true; for (i = 0; i < input_size; i++) { if(C[i] != h_output[i]){ status = false; printf("%d: %lu -- %lu\n", i, C[i], h_output[i]); } } if (status) { printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] Outputs are equal\n"); } else { printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] Outputs differ!\n"); } // Deallocation free(A); free(C); free(C2); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SCAN-RSS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(SCAN-RSS_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/dpu/task.c ================================================ /* * Scan with multiple tasklets (Reduce-scan-scan) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; T message_partial_count; // Reduction in each tasklet T __attribute__ ((noinline)) reduction(T *input){ T output = 0; #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output += input[j]; } return output; } // Scan in each tasklet T __attribute__ ((noinline)) scan(T *output, T *input){ output[0] = input[0]; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { output[j] = output[j - 1] + input[j]; } return output[REGS - 1]; } // Handshake with adjacent tasklets T __attribute__ ((noinline)) handshake_sync(T l_count, unsigned int tasklet_id){ T p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Add in each tasklet void __attribute__ ((noinline)) add_(T *output, T p_count){ #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output[j] += p_count; } } extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Reduction int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); // Local count T l_count = 0; for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Reduction in each tasklet l_count += reduction(cache_A); } // Reduce local counts message[tasklet_id] = l_count; // Single-runtime reduction // Barrier barrier_wait(&my_barrier); if(tasklet_id == 0){ for (unsigned int each_tasklet = 1; each_tasklet < NR_TASKLETS; each_tasklet++){ message[0] += message[each_tasklet]; } // Total count in this DPU result->t_count = message[0]; } return 0; } // Scan int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = DPU_INPUT_ARGUMENTS.t_count; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Scan in each tasklet T l_count = scan(cache_B, cache_A); // Sync with adjacent tasklets T p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Add in each tasklet add_(cache_B, message_partial_count + p_count); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define REGS 128 struct dpu_arguments_t { int size; int kernel; long t_count; }; struct dpu_results_t { long t_count; }; void read_input(long* A, int nr_elements, int nr_elements_round) { for (int i = 0; i < nr_elements; i++) { A[i] = i % 100; } for (int i = nr_elements; i < nr_elements_round; i++) { A[i] = 0; } } void scan_host(long* C, long* A, int nr_elements) { C[0] = A[0]; for (int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i]; } } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { int* A; long* C; long* C2; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); long accum = 0; int input_size = DATA_PREP_PARAMS; int input_size_dpu_ = divceil(input_size, nr_of_dpus); int input_size_dpu_round = (input_size_dpu_ % (NUM_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NUM_TASKLETS * REGS)) : input_size_dpu_; A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); long *bufferA = A; long *bufferC = C2; read_input(A, input_size, input_size_dpu_round * nr_of_dpus); scan_host(C, A, input_size); int input_size_dpu = input_size_dpu_round; int kernel = 0; struct dpu_arguments_t input_arguments; input_arguments.size = input_size_dpu * sizeof(long); input_arguments.kernel = kernel; input_arguments.t_count = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferA[input_size_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(long), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_results_t* results = malloc(nr_of_dpus * sizeof(struct dpu_results_t)); long* results_scan = malloc(nr_of_dpus * sizeof(long)); accum = 0; struct dpu_results_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_results_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_results_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for (int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(each_tasklet == 0) { results[i].t_count = results_retrieve[i * NUM_TASKLETS + each_tasklet].t_count; } } long temp = results[i].t_count; results_scan[i] = accum; accum += temp; } kernel = 1; struct dpu_arguments_t* input_arguments_2 = malloc(NUM_DPUS * sizeof(struct dpu_arguments_t)); for(int i=0; i profile/out${i}_tl16_bl10_dpu11 wait make clean wait done ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif #define REGS (BLOCK_SIZE >> DIV) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; T t_count; } dpu_arguments_t; typedef struct { T t_count; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-RSS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 BL ?= 10 TYPE ?= INT64 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT64) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SCAN-SSA/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(SCAN-SSA_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/dpu/task.c ================================================ /* * Scan with multiple tasklets (Scan-scan-add) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets T message[NR_TASKLETS]; T message_partial_count; // Scan in each tasklet T __attribute__ ((noinline)) scan(T *output, T *input){ output[0] = input[0]; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { output[j] = output[j - 1] + input[j]; } return output[REGS - 1]; } // Handshake with adjacent tasklets T __attribute__ ((noinline)) handshake_sync(T l_count, unsigned int tasklet_id){ T p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Add in each tasklet void __attribute__ ((noinline)) add_(T *output, T p_count){ #pragma unroll for(unsigned int j = 0; j < REGS; j++) { output[j] += p_count; } } extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Scan-(handshake)scan int main_kernel1() { #if 1 // Comment out for appendix experiment unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = DPU_INPUT_ARGUMENTS.t_count; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((const __mram_ptr void*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // Scan in each tasklet T l_count = scan(cache_B, cache_A); // Sync with adjacent tasklets T p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Add in each tasklet add_(cache_B, message_partial_count + p_count); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } #endif return 0; } // Add int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T t_count = DPU_INPUT_ARGUMENTS.t_count; for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_B + byte_index), cache_A, BLOCK_SIZE); // Add in each tasklet add_(cache_A, t_count); // Write cache to current MRAM block mram_write(cache_A, (__mram_ptr void*)(mram_base_addr_B + byte_index), BLOCK_SIZE); } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define REGS 128 struct dpu_arguments_t { int size; int kernel; long t_count; }; struct dpu_results_t { long t_count; }; void read_input(long* A, int nr_elements, int nr_elements_round) { for (int i = 0; i < nr_elements; i++) { A[i] = i % 100; } for (int i = nr_elements; i < nr_elements_round; i++) { A[i] = 0; } } void scan_host(long* C, long* A, int nr_elements) { C[0] = A[0]; for (int i = 1; i < nr_elements; i++) { C[i] = C[i - 1] + A[i]; } } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { int* A; long* C; long* C2; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); long accum = 0; int input_size = DATA_PREP_PARAMS; int input_size_dpu_ = divceil(input_size, nr_of_dpus); int input_size_dpu_round = (input_size_dpu_ % (NUM_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NUM_TASKLETS * REGS)) : input_size_dpu_; A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); long *bufferA = A; long *bufferC = C2; read_input(A, input_size, input_size_dpu_round * nr_of_dpus); scan_host(C, A, input_size); int input_size_dpu = input_size_dpu_round; int kernel = 0; struct dpu_arguments_t input_arguments; input_arguments.size = input_size_dpu * sizeof(long); input_arguments.kernel = kernel; input_arguments.t_count = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferA[input_size_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(long), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_results_t* results = malloc(nr_of_dpus * sizeof(struct dpu_results_t)); long* results_scan = malloc(nr_of_dpus * sizeof(long)); accum = 0; struct dpu_results_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_results_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_results_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for (int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(each_tasklet == NUM_TASKLETS - 1) { results[i].t_count = results_retrieve[i * NUM_TASKLETS + each_tasklet].t_count; } } long temp = results[i].t_count; results_scan[i] = accum; accum += temp; } kernel = 1; struct dpu_arguments_t* input_arguments_2 = malloc(NUM_DPUS * sizeof(struct dpu_arguments_t)); for(int i=0; i profile/out${i}_tl16_bl10_dpu11 wait make clean wait done ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #ifdef UINT32 #define T uint32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif UINT64 #define T uint64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif INT32 #define T int32_t #define DIV 2 // Shift right to divide by sizeof(T) #elif INT64 #define T int64_t #define DIV 3 // Shift right to divide by sizeof(T) #elif FLOAT #define T float #define DIV 2 // Shift right to divide by sizeof(T) #elif DOUBLE #define T double #define DIV 3 // Shift right to divide by sizeof(T) #elif CHAR #define T char #define DIV 0 // Shift right to divide by sizeof(T) #elif SHORT #define T short #define DIV 1 // Shift right to divide by sizeof(T) #endif #define REGS (BLOCK_SIZE >> DIV) // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; T t_count; } dpu_arguments_t; typedef struct { T t_count; } dpu_results_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SCAN-SSA/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/cpu/Makefile ================================================ all: gcc -o sel -fopenmp app_baseline.c clean: rm sel ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/cpu/README ================================================ Select (SEL) Compilation instructions make Execution instructions ./sel -i 1258291200 -t 4 Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/cpu/app_baseline.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" static uint64_t *A; static uint64_t *B; static uint64_t *C; static uint64_t *C2; static int pos; bool pred(const uint64_t x){ return (x % 2) == 0; } void *create_test_file(unsigned int nr_elements) { //srand(0); A = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); B = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); C = (uint64_t*) malloc(nr_elements * sizeof(uint64_t)); printf("nr_elements\t%u\t", nr_elements); for (int i = 0; i < nr_elements; i++) { //A[i] = (unsigned int) (rand()); A[i] = i+1; B[i] = 0; } } /** * @brief compute output in the host */ static int select_host(int size, int t) { pos = 0; C[pos] = A[pos]; omp_set_num_threads(t); #pragma omp parallel for for(int my = 1; my < size; my++) { if(!pred(A[my])) { int p; #pragma omp atomic update pos++; p = pos; C[p] = A[my]; } } return pos; } // Params --------------------------------------------------------------------- typedef struct Params { char* dpu_type; int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d DPU type (default=fsim)" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=2)" "\n -e # of timed repetition iterations (default=5)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16 << 20; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 5; int opt; while((opt = getopt(argc, argv, "hi:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; uint32_t accum = 0; int total_count; // Create an input file with arbitrary data. create_test_file(file_size); Timer timer; start(&timer, 0, 0); total_count = select_host(file_size, p.n_threads); stop(&timer, 0); printf("Total count = %d\t", total_count); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc select.cu -I/usr/local/cuda/include -lm -o select -D COARSENING=32 -D THREADS=512 -D INT64 clean: rm select ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/gpu/README ================================================ Select (SEL) Compilation instructions make Execution instructions ./select 0 50 1258291200 Compilation flags FLOAT - For single precision arrays (Default: Double precision) INT - For integer arrays (Note: Sample predicate is only for INT) THREADS - Thread block size (Default: 1024) COARSENING - Coarsening factor (Default: 16 (SP and INT); 8 (DP)) ATOMIC - Global atomics for synchronization (Default: No atomics) Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/gpu/ds.h ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include #include #include #include #include #include #include #include #ifdef FLOAT #define T float #elif INT #define T int #elif INT64 #define T int64_t #else #define T double #endif #ifdef THREADS #define L_DIM THREADS #else #define L_DIM 1024 #endif #ifdef COARSENING #define REGS COARSENING #else #ifdef FLOAT #define REGS 16 #elif INT #define REGS 16 #else #define REGS 8 #endif #endif #ifdef ATOMIC #define ATOM 1 #else #define ATOM 0 #endif #define WARP_SIZE 32 #define PRINT 0 // Dynamic allocation of runtime workgroup id __device__ int dynamic_wg_id(volatile unsigned int *flags, const int num_flags){ __shared__ int gid_; if (threadIdx.x == 0) gid_ = atomicAdd((unsigned int*)&flags[num_flags + 1], 1); __syncthreads(); int my_s = gid_; return my_s; } // Set global synchronization (regular DS) __device__ void ds_sync(volatile unsigned int *flags, const int my_s){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} atomicOr((unsigned int*)&flags[my_s + 1], 1); } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} flags[my_s + 1] = 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS) __device__ void ds_sync_irregular(volatile unsigned int *flags, const int my_s, int *count){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} int flag = flags[my_s]; atomicAdd((unsigned int*)&flags[my_s + 1], flag + *count); *count = flag - 1; } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} int flag = flags[my_s]; flags[my_s + 1] = flag + *count; *count = flag - 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS Partition) __device__ void ds_sync_irregular_partition(volatile unsigned int *flags1, volatile unsigned int *flags2, const int my_s, int *count1, int *count2){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags1[my_s], 0) == 0){} int flag2 = flags2[my_s]; atomicAdd((unsigned int*)&flags2[my_s + 1], flag2 + *count); int flag1 = flags1[my_s]; atomicAdd((unsigned int*)&flags1[my_s + 1], flag1 + *count); *count1 = flag1 - 1; *count2 = flag2 - 1; } #else if (threadIdx.x == 0){ while (flags1[my_s] == 0){} int flag2 = flags2[my_s]; flags2[my_s + 1] = flag2 + *count2; int flag1 = flags1[my_s]; flags1[my_s + 1] = flag1 + *count1; *count1 = flag1 - 1; *count2 = flag2 - 1; } #endif __syncthreads(); } // Reduction kernel (CUDA SDK reduce6) template __device__ void reduction(S *count, S local_cnt){ __shared__ S sdata[L_DIM]; unsigned int tid = threadIdx.x; S mySum = local_cnt; // each runtime puts its local sum into shared memory sdata[tid] = local_cnt; __syncthreads(); // do reduction in shared mem if ((blockDim.x >= 1024) && (tid < 512)){ sdata[tid] = mySum = mySum + sdata[tid + 512]; } __syncthreads(); if ((blockDim.x >= 512) && (tid < 256)){ sdata[tid] = mySum = mySum + sdata[tid + 256]; } __syncthreads(); if ((blockDim.x >= 256) && (tid < 128)){ sdata[tid] = mySum = mySum + sdata[tid + 128]; } __syncthreads(); if ((blockDim.x >= 128) && (tid < 64)){ sdata[tid] = mySum = mySum + sdata[tid + 64]; } __syncthreads(); #if (__CUDA_ARCH__ >= 300 ) if ( tid < 32 ){ // Fetch final intermediate sum from 2nd warp if (blockDim.x >= 64) mySum += sdata[tid + 32]; // Reduce final warp using shuffle #pragma unroll for (int offset = WARP_SIZE/2; offset > 0; offset /= 2){ //mySum += __shfl_down(mySum, offset); mySum += __shfl_xor(mySum, offset); } } #else // fully unroll reduction within a single warp if ((blockDim.x >= 64) && (tid < 32)){ sdata[tid] = mySum = mySum + sdata[tid + 32]; } __syncthreads(); if ((blockDim.x >= 32) && (tid < 16)){ sdata[tid] = mySum = mySum + sdata[tid + 16]; } __syncthreads(); if ((blockDim.x >= 16) && (tid < 8)){ sdata[tid] = mySum = mySum + sdata[tid + 8]; } __syncthreads(); if ((blockDim.x >= 8) && (tid < 4)){ sdata[tid] = mySum = mySum + sdata[tid + 4]; } __syncthreads(); if ((blockDim.x >= 4) && (tid < 2)){ sdata[tid] = mySum = mySum + sdata[tid + 2]; } __syncthreads(); if ((blockDim.x >= 2) && ( tid < 1)){ sdata[tid] = mySum = mySum + sdata[tid + 1]; } __syncthreads(); #endif // write result for this block to global mem if (tid == 0) *count = mySum; } // Binary prefix-sum (GPU Computing Gems) __device__ inline int lane_id(void) { return threadIdx.x % WARP_SIZE; } __device__ inline int warp_id(void) { return threadIdx.x / WARP_SIZE; } __device__ unsigned int warp_prefix_sums(bool p){ unsigned int b = __ballot(p); return __popc(b & ((1 << lane_id()) - 1)); } __device__ int warp_scan(int val, volatile int *s_data){ #if (__CUDA_ARCH__ < 300 ) int idx = 2 * threadIdx.x - (threadIdx.x & (WARP_SIZE - 1)); s_data[idx] = 0; idx += WARP_SIZE; int t = s_data[idx] = val; s_data[idx] = t = t + s_data[idx - 1]; s_data[idx] = t = t + s_data[idx - 2]; s_data[idx] = t = t + s_data[idx - 4]; s_data[idx] = t = t + s_data[idx - 8]; s_data[idx] = t = t + s_data[idx - 16]; return s_data[idx - 1]; #else int x = val; #pragma unroll for(int offset = 1; offset < 32; offset <<= 1){ // From GTC: Kepler shuffle tips and tricks: #if 0 int y = __shfl_up(x, offset); if(lane_id() >= offset) x += y; #else asm volatile("{" " .reg .s32 r0;" " .reg .pred p;" " shfl.up.b32 r0|p, %0, %1, 0x0;" " @p add.s32 r0, r0, %0;" " mov.s32 %0, r0;" "}" : "+r"(x) : "r"(offset)); #endif } return x - val; #endif } __device__ int block_binary_prefix_sums(int* count, int x){ __shared__ int sdata[L_DIM]; // A. Exclusive scan within each warp int warpPrefix = warp_prefix_sums(x); // B. Store in shared memory if(lane_id() == WARP_SIZE - 1) sdata[warp_id()] = warpPrefix + x; __syncthreads(); // C. One warp scans in shared memory if(threadIdx.x < WARP_SIZE) sdata[threadIdx.x] = warp_scan(sdata[threadIdx.x], sdata); __syncthreads(); // D. Each runtime calculates it final value int thread_out_element = warpPrefix + sdata[warp_id()]; int output = thread_out_element + *count; __syncthreads(); if(threadIdx.x == blockDim.x - 1) *count += (thread_out_element + x); return output; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/gpu/kernel.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ __global__ void select_remove_if(T *matrix_out, T *matrix, int size, volatile unsigned int *flags, struct is_even pred) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(!pred(reg[j])) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } __global__ void select_copy_if(T *matrix_out, T *matrix, int size, volatile unsigned int *flags, struct is_even pred) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(pred(reg[j])) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/baselines/gpu/select.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include "ds.h" // Sample predicate for partition (only for INT) struct is_even{ __host__ __device__ bool operator()(const T &x){ return (x % 2) == 0; } }; #include "kernel.cu" // Sequential CPU version void cpu_copy_if(T* output, T* input, int elements, struct is_even pred){ int pos = 0; for (int i = 0; i < elements; i++){ if(pred(input[i])){ output[pos] = input[i]; pos++; } } } void cpu_remove_if(T* input, int elements, struct is_even pred){ int pos = 0; for (int i = 0; i < elements; i++){ if(!pred(input[i])){ input[pos] = input[i]; pos++; } } } int main(int argc, char **argv){ // Syntax verification if (argc != 4) { printf("Wrong format\n"); printf("Syntax: %s \n",argv[0]); exit(1); } int device = atoi(argv[1]); int input = atoi(argv[2]); int numElements = atoi(argv[3]); size_t size = numElements * sizeof(T); // Set device cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties,device); cudaSetDevice(device); printf("DS Select on %s\n", device_properties.name); printf("Thread block size = %d\n", L_DIM); printf("Coarsening factor = %d\n", REGS); #ifdef FLOAT printf("Single precision array: %d elements\n", numElements); #elif INT printf("Integer array: %d elements\n", numElements); #else printf("Double precision array: %d elements\n", numElements); #endif // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; float time3 = 0; // Allocate the host input vector A T *h_A = (T*)malloc(size); // Allocate the host output vectors T *h_B = (T*)malloc(size); T *h_C = (T*)malloc(size); T *h_D = (T*)malloc(size); // Allocate the device input vector A and output vector B T *d_A = NULL; cudaMalloc((void **)&d_A, size); T *d_B = NULL; cudaMalloc((void **)&d_B, size); #define WARMUP 2 #define REP 10 unsigned int flagM1 = 0; unsigned int flagM2 = 0; for(int iteration = 0; iteration < REP+WARMUP; iteration++){ // Initialize the host input vectors srand(2014); for(int i = 0; i < numElements; i++) h_A[i] = i % 2 != 0 ? i:i+1; int M = (numElements * input)/100; int m = M; while(m>0){ int x = (int)(numElements*(((float)rand()/(float)RAND_MAX))); if(h_A[x] % 2 != 0){ h_A[x] = x * 2; m--; } } #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_A+i)); } printf("\n"); #endif // Copy the host input vector A in host memory to the device input vector in device memory cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); int ldim = L_DIM; // Atomic flags unsigned int* d_flags = NULL; const int num_flags = numElements % (ldim * REGS) == 0 ? numElements / (ldim * REGS) : numElements / (ldim * REGS) + 1; unsigned int *flags = (unsigned int *)calloc(sizeof(unsigned int), num_flags + 2); flags[0] = 1; flags[num_flags + 1] = 0; cudaMalloc((void **)&d_flags, (num_flags + 2) * sizeof(unsigned int)); cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); // Number of work-groups/runtime blocks int num_wg = num_flags; // Start timer cudaEventRecord( start, 0 ); // Kernel launch (Copy_if) select_copy_if<<>>(d_B, d_A, numElements, d_flags, is_even()); cudaMemcpy(&flagM1, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // Stop timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time2 += time1; if(iteration == REP+WARMUP-1){ float timer = time2 / REP; double bw = (double)((numElements + flagM1) * sizeof(T)) / (double)(timer * 1000000.0); printf("Copy_if - Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Atomic flags cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); free(flags); // Start timer cudaEventRecord( start, 0 ); // Kernel launch (Remove_if) select_remove_if<<>>(d_A, d_A, numElements, d_flags, is_even()); cudaMemcpy(&flagM2, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time3 += time1; if(iteration == REP+WARMUP-1){ float timer = time3 / REP; double bw = (double)((numElements + flagM2) * sizeof(T)) / (double)(timer * 1000000.0); printf("Remove_if - Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Free flags cudaFree(d_flags); } // Copy to host memory cudaMemcpy(h_B, d_B, size, cudaMemcpyDeviceToHost); cudaMemcpy(h_C, d_A, size, cudaMemcpyDeviceToHost); // CPU execution for comparison cpu_copy_if(h_D, h_A, numElements, is_even()); cpu_remove_if(h_A, numElements, is_even()); // Verify that the result vector is correct #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_B+i)); } printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_D+i)); } printf("\n"); #endif for (int i = 0; i < flagM1 - 1; ++i){ if (h_B[i] != h_D[i]){ fprintf(stderr, "Copy_if - Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } for (int i = 0; i < flagM2 - 1; ++i){ if (h_C[i] != h_A[i]){ fprintf(stderr, "Remove_if - Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } printf("Test PASSED\n"); // Free device global memory cudaFree(d_A); cudaFree(d_B); cudaEventDestroy(start); cudaEventDestroy(stop); // Free host memory free(h_A); free(h_B); free(h_C); free(h_D); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/SEL/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(SEL_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/dpu/task.c ================================================ /* * Select with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets uint32_t message[NR_TASKLETS]; uint32_t message_partial_count; // SEL in each tasklet unsigned int __attribute__ ((noinline)) select(T *output, T *input){ unsigned int pos = 0; #pragma unroll for(unsigned int j = 0; j < REGS; j++) { if(!pred(input[j])) { output[pos] = input[j]; pos++; } } return pos; } // Handshake with adjacent tasklets unsigned int __attribute__ ((noinline)) handshake_sync(unsigned int l_count, unsigned int tasklet_id){ unsigned int p_count; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; } else p_count = 0; // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; handshake_notify(); } return p_count; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1) message_partial_count = 0; // Barrier barrier_wait(&my_barrier); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // SELECT in each tasklet uint32_t l_count = select(cache_B, cache_A); // In-place or out-of-place? // Sync with adjacent tasklets uint32_t p_count = handshake_sync(l_count, tasklet_id); // Barrier barrier_wait(&my_barrier); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + (message_partial_count + p_count) * sizeof(T)), l_count * sizeof(T)); // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ result->t_count = message_partial_count + p_count + l_count; message_partial_count = result->t_count; } } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define REGS 128 struct dpu_arguments_t{ int size; int kernel; }; struct dpu_results_t { int t_count; }; void read_input(long* A, int nr_elements, int nr_elements_round) { for (int i = 0; i < nr_elements; i++) { A[i] = i + 1; } for (int i = nr_elements; i < nr_elements_round; i++) { A[i] = 0; } } int pred (long x) { return (x % 2) == 0; } int select_host(long* C, long* A, int nr_elements) { int pos = 0; for (int i = 0; i < nr_elements; i++) { if(!pred(A[i])) { C[pos] = A[i]; pos++; } } return pos; } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { long* A; long* C; long* C2; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); nr_of_dpus = NUM_DPUS; int accum = 0; int total_count = 0; int input_size = DATA_PREP_PARAMS; int input_size_dpu_ = divceil(input_size, nr_of_dpus); int input_size_dpu_round = (input_size_dpu_ % (NUM_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NUM_TASKLETS * REGS)) : input_size_dpu_; A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); long *bufferA = A; long *bufferC = C2; read_input(A, input_size, input_size_dpu_round * nr_of_dpus); total_count = select_host(C, A, input_size); int input_size_dpu = input_size_dpu_round; int kernel = 0; struct dpu_arguments_t input_arguments; input_arguments.size = input_size_dpu * sizeof(long); input_arguments.kernel = kernel; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferA[input_size_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(long), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_results_t* results = malloc(nr_of_dpus * sizeof(struct dpu_results_t)); int* results_scan = malloc(nr_of_dpus * sizeof(int)); accum = 0; struct dpu_results_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_results_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_results_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for (int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(each_tasklet == NUM_TASKLETS - 1){ results[i].t_count = results_retrieve[i * NUM_TASKLETS + each_tasklet].t_count; } } int temp = results[i].t_count; results_scan[i] = accum; accum += temp; } DPU_FOREACH (dpu_set, dpu, i) { dpu_copy_from(dpu, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(long), &bufferC[results_scan[i]], results[i].t_count * sizeof(long)); } free(results_scan); int status = 1; if(accum != total_count) { status = 0; } for (int i = 0; i < accum; i++) { if(C[i] != bufferC[i]){ status = 0; break; } } assert(status); free(A); free(C); free(C2); dpu_free(dpu_set); return status ? 0 : -1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; typedef struct { uint32_t t_count; } dpu_results_t; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T uint64_t #define REGS (BLOCK_SIZE >> 3) // 64 bits // Sample predicate bool pred(const T x){ return (x % 2) == 0; } #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/SEL/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_DPUS ?= 1 NR_TASKLETS ?= 16 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=g++ CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -lm -pthread DEP=kernel.cpp kernel.h main.cpp support/common.h support/setup.h support/timer.h SRC=main.cpp kernel.cpp EXE=trns all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/README ================================================ In-place matrix transposition (TRNS) Compilation instructions make Execution instructions ./trns -w 0 -r 1 -m 16 -n 8 -o 4096 -p 2556 For more options ./trns -h Read more J. Gomez-Luna et al., “In-place Matrix Transposition on GPUs,” IEEE TPDS, 2016. ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/kernel.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "kernel.h" #include #include #include #include // CPU threads----------------------------------------------------------------- void run_cpu_threads_100(T *input, std::atomic_int *finished, std::atomic_int *head, int A, int B, int b, int threads) { ///////////////// Run CPU worker threads ///////////////////////////////// #if PRINT printf("Starting %d CPU threads\n", threads); #endif std::vector cpu_threads; for(int i = 0; i < threads; i++) { cpu_threads.push_back(std::thread([=]() { T data[b]; T backup[b]; int done; int m = A * B - 1; // Dynamic fetch int gid = (head)->fetch_add(1); while(gid < m) { int next_in_cycle = (gid * A) - m * (gid / B); if(next_in_cycle == gid) { // Dynamic fetch gid = (head)->fetch_add(1); continue; } for(int i = 0; i < b; i++) { data[i] = input[gid * b + i]; } //make sure the read is not cached done = (finished + gid)->load(); for(; done == 0; next_in_cycle = (next_in_cycle * A) - m * (next_in_cycle / B)) { for(int i = 0; i < b; i++) { backup[i] = input[next_in_cycle * b + i]; } done = (finished + next_in_cycle)->exchange(1); if(!done) { for(int i = 0; i < b; i++) { input[next_in_cycle * b + i] = data[i]; } } for(int i = 0; i < b; i++) { data[i] = backup[i]; } } // Dynamic fetch gid = (head)->fetch_add(1); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } // CPU threads----------------------------------------------------------------- void run_cpu_threads_010(T *input, std::atomic_int* head, int a, int b, int tiles, int threads) { ///////////////// Run CPU worker threads ///////////////////////////////// #if PRINT printf("Starting %d CPU threads\n", threads); #endif std::vector cpu_threads; for(int i = 0; i < threads; i++) { cpu_threads.push_back(std::thread([=]() { T tile[a * b]; int m = a * b - 1; // Dynamic fetch int gid = (head)->fetch_add(1); while(gid < tiles) { T* input_array = input + a * b * gid; for (int j = 0; j < a * b; j++) { int next = (j * a)-m*(j/b); tile[next] = input_array[j]; } for (int j = 0; j < a * b; j++) { input_array[j] = tile[j]; } // Dynamic fetch gid = (head)->fetch_add(1); } })); } std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); }); } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include "support/common.h" void run_cpu_threads_100(T *input, std::atomic_int *finished, std::atomic_int *head, int A, int B, int b, int threads); void run_cpu_threads_010(T *input, std::atomic_int *head, int m, int n, int tiles, int threads); ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include #include // Params --------------------------------------------------------------------- struct Params { int n_threads; int n_warmup; int n_reps; int M_; int m; int N_; int n; Params(int argc, char **argv) { n_threads = 4; n_warmup = 5; n_reps = 50; M_ = 128; m = 16; N_ = 128; n = 8; int opt; while((opt = getopt(argc, argv, "ht:w:r:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'n': n = atoi(optarg); break; case 'o': M_ = atoi(optarg); break; case 'p': N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } } void usage() { fprintf(stderr, "\nUsage: ./trns [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of host threads (default=4)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n TRNS only supports CPU-only or GPU-only execution" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=128 elements)" "\n -p N_ (default=128 elements)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(T *x_vector, const Params &p) { int in_size = p.M_ * p.m * p.N_ * p.n; srand(5432); for(int i = 0; i < in_size; i++) { x_vector[i] = ((T)(rand() % 100) / 100); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { const Params p(argc, argv); Timer timer; // Allocate timer.start("Allocation"); int M_ = p.M_; int m = p.m; int N_ = p.N_; int n = p.n; int in_size = M_ * m * N_ * n; int finished_size = M_ * m * N_; T * h_in_out = (T *)malloc(in_size * sizeof(T)); std::atomic_int *h_finished = (std::atomic_int *)malloc(sizeof(std::atomic_int) * finished_size); std::atomic_int *h_head = (std::atomic_int *)malloc(N_ * sizeof(std::atomic_int)); ALLOC_ERR(h_in_out, h_finished, h_head); T *h_in_backup = (T *)malloc(in_size * sizeof(T)); ALLOC_ERR(h_in_backup); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); read_input(h_in_out, p); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); timer.stop("Initialization"); timer.print("Initialization", 1); memcpy(h_in_backup, h_in_out, in_size * sizeof(T)); // Backup for reuse across iterations // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset memcpy(h_in_out, h_in_backup, in_size * sizeof(T)); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 1"); // Launch CPU threads std::thread main_thread_1(run_cpu_threads_100, h_in_out, h_finished, h_head, M_ * m, N_, n, p.n_threads); //M_ * m * N_); main_thread_1.join(); // end timer if(rep >= p.n_warmup) timer.stop("Step 1"); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 2"); // Launch CPU threads std::thread main_thread_2(run_cpu_threads_010, h_in_out, h_head, m, n, M_ * N_, p.n_threads); main_thread_2.join(); // end timer if(rep >= p.n_warmup) timer.stop("Step 2"); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); // start timer if(rep >= p.n_warmup) timer.start("Step 3"); // Launch CPU threads for(int i = 0; i < N_; i++){ std::thread main_thread_3(run_cpu_threads_100, h_in_out + i * M_ * n * m, h_finished + i * M_ * n, h_head + i, M_, n, m, p.n_threads); //M_ * n); main_thread_3.join(); } // end timer if(rep >= p.n_warmup) timer.stop("Step 3"); } timer.print("Step 1", p.n_reps); timer.print("Step 2", p.n_reps); timer.print("Step 3", p.n_reps); // Verify answer //verify(h_in_out, h_in_backup, M_ * m, N_ * n, 1); // Free memory timer.start("Deallocation"); free(h_in_out); free(h_finished); free(h_head); free(h_in_backup); timer.stop("Deallocation"); timer.print("Deallocation", 1); printf("Test Passed\n"); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #ifndef DOUBLE_PRECISION #define DOUBLE_PRECISION 1 #endif #if DOUBLE_PRECISION #define T double #else #define T float #endif #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/support/setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { time[name] = 0.0; } gettimeofday(&startTime[name], NULL); } void stop(string name) { gettimeofday(&stopTime[name], NULL); time[name] += (stopTime[name].tv_sec - startTime[name].tv_sec) * 1000000.0 + (stopTime[name].tv_usec - startTime[name].tv_usec); } void print(string name, int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / (1000 * REP)); } }; ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/cpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include inline int compare_output(T *output, T *ref, int dim) { int i; for(i = 0; i < dim; i++) { T diff = fabs(ref[i] - output[i]); if((diff - 0.0f) > 0.00001f && diff > 0.01 * fabs(ref[i])) { printf("line: %d ref: %f actual: %f diff: %f\n", i, ref[i], output[i], diff); exit(EXIT_FAILURE); } } return 0; } // Sequential transposition for comparison purposes //[w][h/t][t] to [h/t][w][t] static void trns_host(T* input, unsigned int A, unsigned int B, unsigned int b){ T* output = (T*) malloc(sizeof(T) * A * B * b); unsigned int next; for (unsigned int j = 0; j < b; j++){ for (unsigned int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (unsigned int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } inline void verify(T *input2, T *input, int height, int width, int tile_size) { trns_host(input, height, width, tile_size); compare_output(input2, input, height * width); } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/Makefile ================================================ # # Copyright (c) 2016 University of Cordoba and University of Illinois # All rights reserved. # # Developed by: IMPACT Research Group # University of Cordoba and University of Illinois # http://impact.crhc.illinois.edu/ # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # with the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # > Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimers. # > Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimers in the # documentation and/or other materials provided with the distribution. # > Neither the names of IMPACT Research Group, University of Cordoba, # University of Illinois nor the names of its contributors may be used # to endorse or promote products derived from this Software without # specific prior written permission. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH # THE SOFTWARE. # CXX=/usr/local/cuda/bin/nvcc CXX_FLAGS=-std=c++11 LIB=-L/usr/lib/ -L$/usr/local/cuda/lib64/ -lm INC=-I/usr/local/cuda/include/ DEP=kernel.h main.cpp kernel.cu support/common.h support/cuda-setup.h support/timer.h support/verify.h SRC=main.cpp kernel.cu EXE=trns all: $(CXX) $(CXX_FLAGS) $(SRC) $(LIB) $(INC) -o $(EXE) clean: rm -f $(EXE) ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/README ================================================ In-place matrix transposition (TRNS) Compilation instructions make Execution instructions ./trns -w 0 -r 1 -m 16 -n 8 -o 4096 -p 2556 -i 64 For more options ./trns -h Read more J. Gomez-Luna et al., “In-place Matrix Transposition on GPUs,” IEEE TPDS, 2016. ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/kernel.cu ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/common.h" extern __shared__ int l_mem[]; // GPU kernel ------------------------------------------------------------------------------------------ __global__ void PTTWAC_soa_asta(int A, int B, int b, T *input, int *finished, int *head) { int* done = l_mem; int* gid_ = &done[1]; const int tid = threadIdx.x; int m = A * B - 1; if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); while(gid_[0] < m) { int next_in_cycle = (gid_[0] * A) - m * (gid_[0] / B); if(next_in_cycle == gid_[0]) { if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); continue; } T data1, data2, data3, data4; int i = tid; if(i < b) data1 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data2 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data3 = input[gid_[0] * b + i]; i += blockDim.x; if(i < b) data4 = input[gid_[0] * b + i]; if(tid == 0) { //make sure the read is not cached done[0] = atomicAdd(&finished[gid_[0]], 0); } __syncthreads(); for(; done[0] == 0; next_in_cycle = (next_in_cycle * A) - m * (next_in_cycle / B)) { T backup1, backup2, backup3, backup4; i = tid; if(i < b) backup1 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup2 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup3 = input[next_in_cycle * b + i]; i += blockDim.x; if(i < b) backup4 = input[next_in_cycle * b + i]; if(tid == 0) { done[0] = atomicExch(&finished[next_in_cycle], (int)1); } __syncthreads(); if(!done[0]) { i = tid; if(i < b) input[next_in_cycle * b + i] = data1; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data2; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data3; i += blockDim.x; if(i < b) input[next_in_cycle * b + i] = data4; } i = tid; if(i < b) data1 = backup1; i += blockDim.x; if(i < b) data2 = backup2; i += blockDim.x; if(i < b) data3 = backup3; i += blockDim.x; if(i < b) data4 = backup4; } if(tid == 0) // Dynamic fetch gid_[0] = atomicAdd(&head[0], 1); __syncthreads(); } } cudaError_t call_PTTWAC_soa_asta(int blocks, int threads, int A, int B, int b, T *input, int *finished, int *head, int l_mem_size){ dim3 dimGrid(blocks); dim3 dimBlock(threads); PTTWAC_soa_asta<<>>(A, B, b, input, finished, head); cudaError_t err = cudaGetLastError(); return err; } __global__ void BS_marshal(T *input, int tile_size, int width) { T* tile = (T*)l_mem; int tidx = threadIdx.x; int m = width*tile_size-1; int bid = blockIdx.x; input += tile_size*width*bid; for (int i = tidx; i < tile_size*width; i+=blockDim.x) { int next = (i * tile_size)-m*(i/width); tile[next] = input[i]; } __syncthreads(); for (int i = tidx; i < tile_size*width; i+=blockDim.x) { input[i] = tile[i]; } } cudaError_t call_BS_marshal(int blocks, int threads, int m, int n, T *input, int l_mem_size){ dim3 dimGrid(blocks); dim3 dimBlock(threads); BS_marshal<<>>(input, m, n); cudaError_t err = cudaGetLastError(); return err; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/kernel.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "cuda_runtime.h" #include #include #include "support/common.h" cudaError_t call_PTTWAC_soa_asta(int blocks, int threads, int A, int B, int b, T *input, int *finished, int *head, int l_mem_size); cudaError_t call_BS_marshal(int blocks, int threads, int m, int n, T *input, int l_mem_size); ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/main.cpp ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "support/cuda-setup.h" #include "kernel.h" #include "support/common.h" #include "support/timer.h" #include "support/verify.h" #include #include #include #include // Params --------------------------------------------------------------------- struct Params { int device; int n_gpu_threads; int n_gpu_blocks; int n_threads; int n_warmup; int n_reps; int M_; int m; int N_; int n; Params(int argc, char **argv) { device = 0; n_gpu_threads = 64; n_gpu_blocks = 16; n_warmup = 5; n_reps = 50; M_ = 128; m = 16; N_ = 128; n = 8; int opt; while((opt = getopt(argc, argv, "hd:i:g:t:w:r:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'd': device = atoi(optarg); break; case 'i': n_gpu_threads = atoi(optarg); break; case 'g': n_gpu_blocks = atoi(optarg); break; case 't': n_threads = atoi(optarg); break; case 'w': n_warmup = atoi(optarg); break; case 'r': n_reps = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 'n': n = atoi(optarg); break; case 'o': M_ = atoi(optarg); break; case 'p': N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert((n_gpu_threads > 0 && n_gpu_blocks > 0) && "TRNS only runs on CPU-only or GPU-only: './trns -g 0' or './trns -t 0'"); } void usage() { fprintf(stderr, "\nUsage: ./trns [options]" "\n" "\nGeneral options:" "\n -h help" "\n -d CUDA device ID (default=0)" "\n -i # of device threads per block (default=64)" "\n -g # of device blocks (default=16)" "\n -w # of untimed warmup iterations (default=5)" "\n -r # of timed repetition iterations (default=50)" "\n" "\nData-partitioning-specific options:" "\n TRNS only supports CPU-only or GPU-only execution" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=128 elements)" "\n -p N_ (default=128 elements)" "\n"); } }; // Input Data ----------------------------------------------------------------- void read_input(T *x_vector, const Params &p) { int in_size = p.M_ * p.m * p.N_ * p.n; srand(5432); for(int i = 0; i < in_size; i++) { x_vector[i] = ((T)(rand() % 100) / 100); } } // Main ------------------------------------------------------------------------------------------ int main(int argc, char **argv) { const Params p(argc, argv); CUDASetup setcuda(p.device); Timer timer; cudaError_t cudaStatus; // Allocate timer.start("Allocation"); int M_ = p.M_; int m = p.m; int N_ = p.N_; int n = p.n; int in_size = M_ * m * N_ * n; int finished_size = M_ * m * N_; T * h_in_out = (T *)malloc(in_size * sizeof(T)); std::atomic_int *h_finished = (std::atomic_int *)malloc(sizeof(std::atomic_int) * finished_size); std::atomic_int *h_head = (std::atomic_int *)malloc(N_ * sizeof(std::atomic_int)); ALLOC_ERR(h_in_out, h_finished, h_head); T * d_in_out; int * d_finished; int * d_head; if(p.n_gpu_blocks != 0) { cudaStatus = cudaMalloc((void**)&d_in_out, in_size * sizeof(T)); cudaStatus = cudaMalloc((void**)&d_finished, (p.n_gpu_blocks != 0) ? sizeof(int) * finished_size : 0); cudaStatus = cudaMalloc((void**)&d_head, (p.n_gpu_blocks != 0) ? N_ * sizeof(int) : 0); CUDA_ERR(); } T *h_in_backup = (T *)malloc(in_size * sizeof(T)); ALLOC_ERR(h_in_backup); cudaDeviceSynchronize(); timer.stop("Allocation"); timer.print("Allocation", 1); // Initialize timer.start("Initialization"); const int max_gpu_threads = setcuda.max_gpu_threads(); read_input(h_in_out, p); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); timer.stop("Initialization"); timer.print("Initialization", 1); memcpy(h_in_backup, h_in_out, in_size * sizeof(T)); // Backup for reuse across iterations // Copy to device timer.start("Copy To Device"); if(p.n_gpu_blocks != 0) { cudaStatus = cudaMemcpy(d_in_out, h_in_backup, in_size * sizeof(T), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); } cudaDeviceSynchronize(); timer.stop("Copy To Device"); timer.print("Copy To Device", 1); // Loop over main kernel for(int rep = 0; rep < p.n_warmup + p.n_reps; rep++) { // Reset memcpy(h_in_out, h_in_backup, in_size * sizeof(T)); memset((void *)h_finished, 0, sizeof(std::atomic_int) * finished_size); for(int i = 0; i < N_; i++) h_head[i].store(0); cudaDeviceSynchronize(); // Launch GPU threads if(p.n_gpu_blocks > 0) { // Kernel launch assert(p.n_gpu_threads <= max_gpu_threads && "The runtime block size is greater than the maximum runtime block size that can be used on this device"); cudaStatus = cudaMemcpy(d_in_out, h_in_backup, in_size * sizeof(T), cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); // start timer if(rep >= p.n_warmup) timer.start("Step 1"); // Step 1 cudaStatus = call_PTTWAC_soa_asta(M_ * m * N_, p.n_gpu_threads, M_ * m, N_, n, d_in_out, (int*)d_finished, (int*)d_head, sizeof(int) + sizeof(int)); CUDA_ERR(); // end timer if(rep >= p.n_warmup) timer.stop("Step 1"); // start timer if(rep >= p.n_warmup) timer.start("Step 2"); // Step 2 cudaStatus = call_BS_marshal(M_ * N_, p.n_gpu_threads, m, n, d_in_out, m * n * sizeof(T)); CUDA_ERR(); // end timer if(rep >= p.n_warmup) timer.stop("Step 2"); cudaStatus = cudaMemcpy(d_finished, h_finished, sizeof(int) * finished_size, cudaMemcpyHostToDevice); cudaStatus = cudaMemcpy(d_head, h_head, N_ * sizeof(int), cudaMemcpyHostToDevice); CUDA_ERR(); // start timer if(rep >= p.n_warmup) timer.start("Step 3"); // Step 3 for(int i = 0; i < N_; i++){ cudaStatus = call_PTTWAC_soa_asta(M_ * n, p.n_gpu_threads, M_, n, m, d_in_out + i * M_ * n * m, (int*)d_finished + i * M_ * n, (int*)d_head + i, sizeof(int) + sizeof(int)); CUDA_ERR(); } // end timer if(rep >= p.n_warmup) timer.stop("Step 3"); } cudaDeviceSynchronize(); } timer.print("Step 1", p.n_reps); timer.print("Step 2", p.n_reps); timer.print("Step 3", p.n_reps); // Copy back timer.start("Copy Back and Merge"); if(p.n_gpu_blocks != 0) { cudaStatus = cudaMemcpy(h_in_out, d_in_out, in_size * sizeof(T), cudaMemcpyDeviceToHost); CUDA_ERR(); cudaDeviceSynchronize(); } timer.stop("Copy Back and Merge"); timer.print("Copy Back and Merge", 1); // Verify answer verify(h_in_out, h_in_backup, M_ * m, N_ * n, 1); // Free memory timer.start("Deallocation"); free(h_in_out); free(h_finished); free(h_head); if(p.n_gpu_blocks != 0) { cudaStatus = cudaFree(d_in_out); cudaStatus = cudaFree(d_finished); cudaStatus = cudaFree(d_head); CUDA_ERR(); } free(h_in_backup); cudaDeviceSynchronize(); timer.stop("Deallocation"); timer.print("Deallocation", 1); // Release timers timer.release("Allocation"); timer.release("Initialization"); timer.release("Copy To Device"); timer.release("Step 1"); timer.release("Step 2"); timer.release("Step 3"); timer.release("Copy Back and Merge"); timer.release("Deallocation"); printf("Test Passed\n"); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/support/common.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #ifndef _COMMON_H_ #define _COMMON_H_ #ifndef DOUBLE_PRECISION #define DOUBLE_PRECISION 1 #endif #if DOUBLE_PRECISION #define T long int // double #else #define T int // float #endif #define PRINT 0 #define divceil(n, m) (((n)-1) / (m) + 1) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/support/cuda-setup.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include // Allocation error checking #define ERR_1(v1) \ if(v1 == NULL) { \ fprintf(stderr, "Allocation error at %s, %d\n", __FILE__, __LINE__); \ exit(-1); \ } #define ERR_2(v1,v2) ERR_1(v1) ERR_1(v2) #define ERR_3(v1,v2,v3) ERR_2(v1,v2) ERR_1(v3) #define ERR_4(v1,v2,v3,v4) ERR_3(v1,v2,v3) ERR_1(v4) #define ERR_5(v1,v2,v3,v4,v5) ERR_4(v1,v2,v3,v4) ERR_1(v5) #define ERR_6(v1,v2,v3,v4,v5,v6) ERR_5(v1,v2,v3,v4,v5) ERR_1(v6) #define GET_ERR_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME #define ALLOC_ERR(...) GET_ERR_MACRO(__VA_ARGS__,ERR_6,ERR_5,ERR_4,ERR_3,ERR_2,ERR_1)(__VA_ARGS__) #define CUDA_ERR() \ if(cudaStatus != cudaSuccess) { \ fprintf(stderr, "CUDA error: %s\n at %s, %d\n", cudaGetErrorString(cudaStatus), __FILE__, __LINE__); \ exit(-1); \ } struct CUDASetup { cudaDeviceProp device_prop; CUDASetup(int device) { cudaError_t cudaStatus; cudaStatus = cudaSetDevice(device); CUDA_ERR(); cudaStatus = cudaGetDeviceProperties(&device_prop, device); CUDA_ERR(); fprintf(stderr, "%s\t", device_prop.name); } int max_gpu_threads() { return device_prop.maxThreadsPerBlock; } }; ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include #include #include #include #include using namespace std; struct Timer { map startTime; map stopTime; map time; void start(string name) { if(!time.count(name)) { cudaEventCreate(&startTime[name]); cudaEventCreate(&stopTime[name]); time[name] = 0.0; } cudaEventRecord(startTime[name], 0); } void stop(string name) { cudaEventRecord(stopTime[name],0); cudaEventSynchronize(stopTime[name]); float part_time = 0.0; cudaEventElapsedTime(&part_time, startTime[name], stopTime[name]); time[name] += part_time; } void print(string name, unsigned int REP) { printf("%s Time (ms): %f\n", name.c_str(), time[name] / REP); } void release(string name){ cudaEventDestroy(startTime[name]); cudaEventDestroy(stopTime[name]); } }; ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/baselines/gpu/support/verify.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include "common.h" #include inline int compare_output(T *output, T *ref, int dim) { int i; for(i = 0; i < dim; i++) { T diff = fabs(ref[i] - output[i]); if((diff - 0.0f) > 0.00001f && diff > 0.01 * fabs(ref[i])) { printf("line: %d ref: %f actual: %f diff: %f\n", i, ref[i], output[i], diff); exit(EXIT_FAILURE); } } return 0; } // Sequential transposition for comparison purposes //[w][h/t][t] to [h/t][w][t] static void trns_host(T* input, unsigned int A, unsigned int B, unsigned int b){ T* output = (T*) malloc(sizeof(T) * A * B * b); unsigned int next; for (unsigned int j = 0; j < b; j++){ for (unsigned int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (unsigned int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } inline void verify(T *input2, T *input, int height, int width, int tile_size) { trns_host(input, height, width, tile_size); compare_output(input2, input, height * width); } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/dpu/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/TRNS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(TRNS_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/dpu/task.c ================================================ /* * 3-step matrix transposition with multiple tasklets * Acks: Stefano Ballarin (P&S PIM Fall 2020) * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; uint32_t curr_tile = 0; // protected by MUTEX uint32_t get_tile(); void read_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n); void write_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n); void read_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m); void write_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m); _Bool get_done(uint32_t done_array_step3, uint32_t address, T* read_done); _Bool get_and_set_done(uint32_t done_array_step3, uint32_t address, T* read_done); // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); // Mutexes MUTEX_INIT(tile_mutex); MUTEX_INIT(done_mutex); extern int main_kernel1(void); extern int main_kernel2(void); int (*kernels[nr_kernels])(void) = {main_kernel1, main_kernel2}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // Step 2: 0010 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t A = (uint32_t)DPU_MRAM_HEAP_POINTER; // A in MRAM uint32_t M_ = DPU_INPUT_ARGUMENTS.M_; uint32_t m = DPU_INPUT_ARGUMENTS.m; uint32_t n = DPU_INPUT_ARGUMENTS.n; T* data = (T*) mem_alloc(m * n * sizeof(T)); T* backup = (T*) mem_alloc(m * n * sizeof(T)); for(unsigned int tile = tasklet_id; tile < M_; tile += NR_TASKLETS){ read_tile_step2(A, tile * m * n, data, m, n); for (unsigned int i = 0; i < m * n; i++){ backup[(i * m) - (m * n - 1) * (i / n)] = data[i]; } write_tile_step2(A, tile * m * n, backup, m, n); } return 0; } // Step 3: 0100 int main_kernel2() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t m = DPU_INPUT_ARGUMENTS.m; uint32_t n = DPU_INPUT_ARGUMENTS.n; uint32_t M_ = DPU_INPUT_ARGUMENTS.M_; uint32_t done_array = (uint32_t)(DPU_MRAM_HEAP_POINTER + M_ * m * n * sizeof(T)); const uint32_t tile_max = M_ * n - 1; // Tile id upper bound T* data = (T*)mem_alloc(sizeof(T) * m); T* backup = (T*)mem_alloc(sizeof(T) * m); T* read_done = (T*)mem_alloc(sizeof(T)); uint32_t tile; _Bool done; tile = get_tile(); while (tile < tile_max){ uint32_t next_in_cycle = ((tile * M_) - tile_max * (tile / n)); if (next_in_cycle == tile){ tile = get_tile(); continue; } read_tile_step3(A, tile * m, data, m); done = get_done(done_array, tile, read_done); for(; done == 0; next_in_cycle = ((next_in_cycle * M_) - tile_max * (next_in_cycle / n))){ read_tile_step3(A, next_in_cycle * m, backup, m); done = get_and_set_done(done_array, next_in_cycle, read_done); if(!done) { write_tile_step3(A, next_in_cycle * m, data, m); } for(uint32_t i = 0; i < m; i++){ data[i] = backup[i]; } } tile = get_tile(); } return 0; } // Auxiliary functions uint32_t __attribute__ ((noinline)) get_tile(){ mutex_lock(tile_mutex); uint32_t value = curr_tile; curr_tile++; mutex_unlock(tile_mutex); return value; } void __attribute__ ((noinline)) read_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n){ int rest = m * n; int transfer; while(rest > 0){ if(rest * sizeof(T) > 2048){ transfer = 2048 / sizeof(T); } else { transfer = rest; } mram_read((__mram_ptr void*)(A + (offset + m * n - rest) * sizeof(T)), variable + (m * n - rest) * sizeof(T), sizeof(T) * transfer); rest -= transfer; } } void __attribute__ ((noinline)) write_tile_step2(uint32_t A, uint32_t offset, T* variable, uint32_t m, uint32_t n){ int rest = m * n; int transfer; while(rest > 0){ if(rest * sizeof(T) > 2048){ transfer = 2048 / sizeof(T); } else { transfer = rest; } mram_write(variable + (m * n - rest) * sizeof(T), (__mram_ptr void*)(A + (offset + m * n - rest) * sizeof(T)), sizeof(T) * transfer); rest -= transfer; } } void __attribute__ ((noinline)) read_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m){ mram_read((__mram_ptr void*)(A + offset * sizeof(T)), variable, sizeof(T) * m); } void __attribute__ ((noinline)) write_tile_step3(uint32_t A, uint32_t offset, T* variable, uint32_t m){ mram_write(variable, (__mram_ptr void*)(A + offset * sizeof(T)), sizeof(T) * m); } _Bool __attribute__ ((noinline)) get_done(uint32_t done_array_step3, uint32_t address, T* read_done){ uint32_t result; mutex_lock(done_mutex); mram_read((__mram_ptr void*)(done_array_step3 + address), read_done, sizeof(T)); result = ((*read_done & (0x01 << (address % sizeof(T)))) != 0); mutex_unlock(done_mutex); return (_Bool)result; } _Bool __attribute__ ((noinline))get_and_set_done(uint32_t done_array_step3, uint32_t address, T* read_done){ uint32_t result; mutex_lock(done_mutex); mram_read((__mram_ptr void*)(done_array_step3 + address), read_done, sizeof(T)); result = ((*read_done & (0x01 << (address % sizeof(T)))) != 0); *read_done |= (0x01 << (address % sizeof(T))); mram_write(read_done, (__mram_ptr void*)(done_array_step3 + address), sizeof(T)); mutex_unlock(done_mutex); return (_Bool)result; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 struct dpu_arguments_t { int m; int n; int M_; int kernel; }; void read_input(long* A, int nr_elements) { for (int i = 0; i < nr_elements; i++) { A[i] = i % 100; } } void trns_host(long* input, int A, int B, int b){ long* output = malloc(sizeof(long) * A * B * b); int next; for (int j = 0; j < b; j++){ for (int i = 0; i < A * B; i++){ next = (i * A) - (A * B - 1) * (i / B); output[next * b + j] = input[i*b+j]; } } for (int k = 0; k < A * B * b; k++){ input[k] = output[k]; } free(output); } int main() { long* A_host; long* A_backup; long* A_result; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; int N_ = 64; int n = 8; int M_ = DATA_PREP_PARAMS; int m = 4; A_host = malloc(M_ * m * N_ * n * sizeof(long)); A_backup = malloc(M_ * m * N_ * n * sizeof(long)); A_result = malloc(M_ * m * N_ * n * sizeof(long)); char* done_host = malloc(M_ * n * sizeof(char)); for (int i = 0; i < M_ * n; i++) { done_host[i] = 0; } read_input(A_host, M_ * m * N_ * n); for (int i = 0; i < M_ * m * N_ * n; i++) { A_backup[i] = A_host[i]; } trns_host(A_host, M_ * m, N_ * n, 1); int curr_dpu = 0; int active_dpus; int active_dpus_before = 0; int first_round = 1; while(curr_dpu < N_){ if((N_ - curr_dpu) > NUM_DPUS){ active_dpus = NUM_DPUS; } else { active_dpus = (N_ - curr_dpu); } if((active_dpus_before != active_dpus) && (!(first_round))){ dpu_free(dpu_set); dpu_alloc(active_dpus, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); nr_of_dpus = active_dpus; } else if (first_round){ dpu_alloc(active_dpus, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); nr_of_dpus = active_dpus; } for(int j = 0; j < M_ * m; j++){ DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &A_backup[j * N_ * n + n * (i + curr_dpu)]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, sizeof(long) * j * n, sizeof(long) * n, DPU_XFER_DEFAULT); } DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, done_host); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, M_ * m * n * sizeof(long), (M_ * n) / 8 == 0 ? 8 : M_ * n, DPU_XFER_DEFAULT); int kernel = 0; struct dpu_arguments_t input_arguments; input_arguments.m = m; input_arguments.n = n; input_arguments.M_ = M_; input_arguments.kernel = kernel; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); kernel = 1; struct dpu_arguments_t input_arguments2; input_arguments2.m = m; input_arguments2.n = n; input_arguments2.M_ = M_; input_arguments2.kernel = kernel; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &input_arguments2); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &A_result[curr_dpu * m * n * M_]); curr_dpu++; } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, sizeof(long) * m * n * M_, DPU_XFER_DEFAULT); if(first_round){ first_round = 0; } } dpu_free(dpu_set); int status = 1; for (int i = 0; i < M_ * m * N_ * n; i++) { if(A_host[i] != A_result[i]){ status = 0; break; } } assert(status); free(A_host); free(A_backup); free(A_result); free(done_host); return status ? 0 : -1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif // Data type #define T int64_t // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t m; uint32_t n; uint32_t M_; enum kernels { kernel1 = 0, kernel2 = 1, nr_kernels = 2, } kernel; } dpu_arguments_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int M_; unsigned int m; unsigned int N_; unsigned int n; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -m m (default=16 elements)" "\n -n n (default=8 elements)" "\n -o M_ (default=12288 elements)" "\n -p N_ (default=1 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.M_ = 12288; p.m = 16; p.N_ = 1; p.n = 8; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hw:e:x:m:n:o:p:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; case 'm': p.m = atoi(optarg); break; case 'n': p.n = atoi(optarg); break; case 'o': p.M_ = atoi(optarg); break; case 'p': p.N_ = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TRNS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 NR_DPUS ?= 1 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS}) COMMON_INCLUDES := support HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -lm DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} -n 131072 ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/TS/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(TS_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/dpu/task.c ================================================ /* * STREAMP implementation of Matrix Profile with multiple tasklets * */ #include #include #include #include #include #include #include #include "common.h" #define DOTPIP BLOCK_SIZE / sizeof(DTYPE) __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_result_t DPU_RESULTS[NR_TASKLETS]; // Dot product void __attribute__ ((noinline)) dot_product(DTYPE *vectorA, DTYPE *vectorA_aux, DTYPE *vectorB, DTYPE * result) { for(uint32_t i = 0; i < BLOCK_SIZE / sizeof(DTYPE); i++) { for(uint32_t j = 0; j < DOTPIP; j++) { if((j + i) > BLOCK_SIZE / sizeof(DTYPE) - 1) { result[j] += vectorA_aux[(j + i) - BLOCK_SIZE / sizeof(DTYPE)] * vectorB[i]; } else { result[j] += vectorA[j + i] * vectorB[i]; } } } } BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int(*kernels[nr_kernels])(void) = {main_kernel1}; int main(void){ // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if(tasklet_id == 0){ mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); // Input arguments uint32_t query_length = DPU_INPUT_ARGUMENTS.query_length; DTYPE query_mean = DPU_INPUT_ARGUMENTS.query_mean; DTYPE query_std = DPU_INPUT_ARGUMENTS.query_std; uint32_t slice_per_dpu = DPU_INPUT_ARGUMENTS.slice_per_dpu; // Boundaries for current tasklet uint32_t myStartElem = tasklet_id * (slice_per_dpu / (NR_TASKLETS)); uint32_t myEndElem = myStartElem + (slice_per_dpu / (NR_TASKLETS)) - 1; // Check time series limit if(myEndElem > slice_per_dpu - query_length) myEndElem = slice_per_dpu - query_length; // Starting address of the current processing block in MRAM uint32_t mem_offset = (uint32_t) DPU_MRAM_HEAP_POINTER; // Starting address of the query subsequence uint32_t current_mram_block_addr_query = (uint32_t)(mem_offset); mem_offset += query_length * sizeof(DTYPE); // Starting address of the time series slice mem_offset += myStartElem * sizeof(DTYPE); uint32_t starting_offset_ts = mem_offset; uint32_t current_mram_block_addr_TS = (uint32_t) mem_offset; // Starting address of the time series means mem_offset += (slice_per_dpu + query_length) * sizeof(DTYPE); uint32_t current_mram_block_addr_TSMean = (uint32_t)(mem_offset); // Starting address of the time series standard deviations mem_offset += (slice_per_dpu + query_length) * sizeof(DTYPE); uint32_t current_mram_block_addr_TSSigma = (uint32_t)(mem_offset); // Initialize local caches to store the MRAM blocks DTYPE *cache_TS = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TS_aux = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_query = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TSMean = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_TSSigma = (DTYPE *) mem_alloc(BLOCK_SIZE); DTYPE *cache_dotprods = (DTYPE *) mem_alloc(BLOCK_SIZE); // Create result structure pointer dpu_result_t *result = &DPU_RESULTS[tasklet_id]; // Auxiliary variables DTYPE distance; DTYPE min_distance = DTYPE_MAX; uint32_t min_index = 0; for(uint32_t i = myStartElem; i < myEndElem; i+= (BLOCK_SIZE / sizeof(DTYPE))) { for(uint32_t d = 0; d < DOTPIP; d++) cache_dotprods[d] = 0; current_mram_block_addr_TS = (uint32_t) starting_offset_ts + (i - myStartElem) * sizeof(DTYPE); current_mram_block_addr_query = (uint32_t) DPU_MRAM_HEAP_POINTER; for(uint32_t j = 0; j < (query_length) / (BLOCK_SIZE / sizeof(DTYPE)); j++) { mram_read((__mram_ptr void const *) current_mram_block_addr_TS, cache_TS, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_TS + BLOCK_SIZE, cache_TS_aux, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_query, cache_query, BLOCK_SIZE); current_mram_block_addr_TS += BLOCK_SIZE; current_mram_block_addr_query += BLOCK_SIZE; dot_product(cache_TS, cache_TS_aux, cache_query, cache_dotprods); } mram_read((__mram_ptr void const *) current_mram_block_addr_TSMean, cache_TSMean, BLOCK_SIZE); mram_read((__mram_ptr void const *) current_mram_block_addr_TSSigma, cache_TSSigma, BLOCK_SIZE); current_mram_block_addr_TSMean += BLOCK_SIZE; current_mram_block_addr_TSSigma += BLOCK_SIZE; for (uint32_t k = 0; k < (BLOCK_SIZE / sizeof(DTYPE)); k++) { distance = 2 * ((DTYPE) query_length - (cache_dotprods[k] - (DTYPE) query_length * cache_TSMean[k] * query_mean) / (cache_TSSigma[k] * query_std)); if(distance < min_distance) { min_distance = distance; min_index = i + k; } } } // Save the result result->minValue = min_distance; result->minIndex = min_index; return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/host/app.c ================================================ #include #include #include #include #include #include #include #include #include #include #include #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 64 #define MAX_DATA_VAL 127 struct dpu_arguments_t { int ts_length; int query_length; int query_mean; int query_std; int slice_per_dpu; int exclusion_zone; int kernel; }; struct dpu_result_t { int minValue; int minIndex; int maxValue; int maxIndex; }; int *create_test_file(int* tSeries, int* query, int ts_elements, int query_elements) { for (int i = 0; i < ts_elements; i++) { tSeries[i] = i % MAX_DATA_VAL; } for (int i = 0; i < query_elements; i++) { query[i] = i % MAX_DATA_VAL; } return tSeries; } void streamp(int* tSeries, int* AMean, int* ASigma, int *minHost, int *minHostIdx, int ProfileLength, int* query, int queryLength, int queryMean, int queryStdDeviation) { int distance; int dotprod; *minHost = 2147483647; *minHostIdx = 0; for (int subseq = 0; subseq < ProfileLength; subseq++) { dotprod = 0; for(int j = 0; j < queryLength; j++) { dotprod += tSeries[j + subseq] * query[j]; } distance = 2 * (queryLength - (dotprod - queryLength * AMean[subseq] * queryMean) / (ASigma[subseq] * queryStdDeviation)); if(distance < *minHost) { *minHost = distance; *minHostIdx = subseq; } } } void compute_ts_statistics(int* tSeries, int* AMean, int* ASigma, int timeSeriesLength, int ProfileLength, int queryLength) { int* ACumSum = malloc(sizeof(int) * timeSeriesLength); ACumSum[0] = tSeries[0]; for (int i = 1; i < timeSeriesLength; i++) { ACumSum[i] = tSeries[i] + ACumSum[i - 1]; } int* ASqCumSum = malloc(sizeof(int) * timeSeriesLength); ASqCumSum[0] = tSeries[0] * tSeries[0]; for (int i = 1; i < timeSeriesLength; i++) { ASqCumSum[i] = tSeries[i] * tSeries[i] + ASqCumSum[i - 1]; } int* ASum = malloc(sizeof(int) * ProfileLength); ASum[0] = ACumSum[queryLength - 1]; for (int i = 0; i < timeSeriesLength - queryLength; i++) { ASum[i + 1] = ACumSum[queryLength + i] - ACumSum[i]; } int* ASumSq = malloc(sizeof(int) * ProfileLength); ASumSq[0] = ASqCumSum[queryLength - 1]; for (int i = 0; i < timeSeriesLength - queryLength; i++) { ASumSq[i + 1] = ASqCumSum[queryLength + i] - ASqCumSum[i]; } int * AMean_tmp = malloc(sizeof(int) * ProfileLength); for (int i = 0; i < ProfileLength; i++) { AMean_tmp[i] = ASum[i] / queryLength; } int* ASigmaSq = malloc(sizeof(int) * ProfileLength); for (int i = 0; i < ProfileLength; i++) { ASigmaSq[i] = ASumSq[i] / queryLength - AMean[i] * AMean[i]; } for (int i = 0; i < ProfileLength; i++) { ASigma[i] = sqrt(ASigmaSq[i]); AMean[i] = AMean_tmp[i]; } free(ACumSum); free(ASqCumSum); free(ASum); free(ASumSq); free(ASigmaSq); free(AMean_tmp); } int main() { int* tSeries = malloc((1 << 15) * sizeof(int)); int* query = malloc((1 << 15) * sizeof(int)); int* AMean = malloc((1 << 15) * sizeof(int)); int* ASigma = malloc((1 << 15) * sizeof(int)); int* minHost = malloc(sizeof(int)); int* minHostIdx = malloc(sizeof(int)); struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(NUM_DPUS, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int ts_size = DATA_PREP_PARAMS; int query_length = 64; if(ts_size % (nr_of_dpus * NUM_TASKLETS*query_length)) { ts_size = ts_size + (nr_of_dpus * NUM_TASKLETS * query_length - ts_size % (nr_of_dpus * NUM_TASKLETS*query_length)); } create_test_file(tSeries, query, ts_size, query_length); compute_ts_statistics(tSeries, AMean, ASigma, ts_size, ts_size - query_length, query_length); int query_mean; int queryMean = 0; for(int i = 0; i < query_length; i++) { queryMean += query[i]; } queryMean /= query_length; query_mean = queryMean; int query_std; int queryStdDeviation; int queryVariance = 0; for(int i = 0; i < query_length; i++) { queryVariance += (query[i] - queryMean) * (query[i] - queryMean); } queryVariance /= query_length; queryStdDeviation = sqrt(queryVariance); query_std = queryStdDeviation; int *bufferTS = tSeries; int *bufferQ = query; int *bufferAMean = AMean; int *bufferASigma = ASigma; int slice_per_dpu = ts_size / nr_of_dpus; int kernel = 0; struct dpu_arguments_t input_arguments; input_arguments.ts_length = ts_size; input_arguments.query_length = query_length; input_arguments.query_mean = query_mean; input_arguments.query_std = query_std; input_arguments.slice_per_dpu = slice_per_dpu; input_arguments.exclusion_zone = 0; input_arguments.kernel = kernel; struct dpu_result_t result; result.minValue = 2147483647; result.minIndex = 0; result.maxValue = 0; result.maxIndex = 0; DPU_FOREACH(dpu_set, dpu, i) { input_arguments.exclusion_zone = 0; dpu_copy_to(dpu, "DPU_INPUT_ARGUMENTS", 0, &input_arguments, sizeof(struct dpu_arguments_t)); } int mem_offset = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, bufferQ); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, query_length * sizeof(int), DPU_XFER_DEFAULT); mem_offset += query_length * sizeof(int); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferTS[slice_per_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset,(slice_per_dpu + query_length)*sizeof(int), DPU_XFER_DEFAULT); mem_offset += ((slice_per_dpu + query_length) * sizeof(int)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferAMean[slice_per_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset, (slice_per_dpu + query_length)*sizeof(int), DPU_XFER_DEFAULT); mem_offset += ((slice_per_dpu + query_length) * sizeof(int)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferASigma[slice_per_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, mem_offset, (slice_per_dpu + query_length)*sizeof(int), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_result_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_result_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_result_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for (int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(results_retrieve[i * NUM_TASKLETS + each_tasklet].minValue < result.minValue && results_retrieve[i * NUM_TASKLETS + each_tasklet].minValue > 0) { result.minValue = results_retrieve[i * NUM_TASKLETS + each_tasklet].minValue; result.minIndex = results_retrieve[i * NUM_TASKLETS + each_tasklet].minIndex + (i * slice_per_dpu); } } } streamp(tSeries, AMean, ASigma, minHost, minHostIdx, ts_size - query_length - 1, query, query_length, query_mean, query_std); int status = (*minHost == result.minValue); assert(status); dpu_free(dpu_set); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #endif // Data type #define DTYPE int32_t #define DTYPE_MAX INT32_MAX typedef struct { uint32_t ts_length; uint32_t query_length; DTYPE query_mean; DTYPE query_std; uint32_t slice_per_dpu; int32_t exclusion_zone; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; }dpu_arguments_t; typedef struct { DTYPE minValue; uint32_t minIndex; DTYPE maxValue; uint32_t maxIndex; }dpu_result_t; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" // Params --------------------------------------------------------------------- typedef struct Params { unsigned long input_size_n; unsigned long input_size_m; int n_warmup; int n_reps; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -n n (TS length. Default=64K elements)" "\n -m m (Query length. Default=256 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size_n = 1 << 16; p.input_size_m = 1 << 8; p.n_warmup = 1; p.n_reps = 3; int opt; while((opt = getopt(argc, argv, "hw:e:n:m:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'n': p.input_size_n = atol(optarg); break; case 'm': p.input_size_m = atol(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/TS/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[5]; struct timeval stopTime[5]; double time[5]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("%f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/CMakeLists.txt ================================================ #add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o $@ ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/cpu/Makefile ================================================ all: gcc -o uni -fopenmp app_baseline.c clean: rm uni ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/cpu/README ================================================ Unique (UNI) Compilation instructions make Execution instructions ./uni -i 1258291200 -t 4 Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/cpu/app_baseline.c ================================================ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" #define T int64_t static int pos; static T *A; static T *B; static T *C; static T *C2; // Create a "test file" static T *create_test_file(unsigned int nr_elements) { //srand(0); A = (T*) malloc(nr_elements * sizeof(T)); B = (T*) malloc(nr_elements * sizeof(T)); C = (T*) malloc(nr_elements * sizeof(T)); printf("nr_elements\t%u\t", nr_elements); for (int i = 0; i < nr_elements; i++) { //A[i] = (unsigned int) (rand()); //A[i] = i+1; //A[i] = i%2==0?i+1:i; A[i] = i%2==0?i:i+1; B[i] = 0; } return A; } // Compute output in the host static int unique_host(int size, int t) { pos = 0; C[pos] = A[pos]; omp_set_num_threads(t); #pragma omp parallel for for(int my = 1; my < size; my++) { if(A[my] != A[my-1]) { int p; #pragma omp atomic update pos++; p = pos; C[p] = A[my]; } } return pos; } // Params typedef struct Params { int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16 << 20; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 8; int opt; while((opt = getopt(argc, argv, "hd:i:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } // Main int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; uint32_t accum = 0; int total_count; // Create an input file with arbitrary data create_test_file(file_size); Timer timer; start(&timer, 0, 0); total_count = unique_host(file_size, p.n_threads); stop(&timer, 0); printf("Total count = %d\t", total_count); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc unique.cu -I/usr/local/cuda/include -lm -o unique -D COARSENING=32 -D THREADS=512 -D INT64 clean: rm unique ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/gpu/README ================================================ Unique (UNI) Compilation instructions make Execution instructions ./unique 0 50 1258291200 Compilation flags FLOAT - For single precision arrays (Default: Double precision) INT - For integer arrays THREADS - Thread block size (Default: 1024) COARSENING - Coarsening factor (Default: 16 (SP and INT); 8 (DP)) ATOMIC - Global atomics for synchronization (Default: No atomics) Read more J. Gomez-Luna et al., “In-place Data Sliding Algorithms for Many-core Architectures,” ICPP 2015. ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/gpu/ds.h ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include #include #include #include #include #include #include #include #ifdef FLOAT #define T float #elif INT #define T int #elif INT64 #define T int64_t #else #define T double #endif #ifdef THREADS #define L_DIM THREADS #else #define L_DIM 1024 #endif #ifdef COARSENING #define REGS COARSENING #else #ifdef FLOAT #define REGS 16 #elif INT #define REGS 16 #else #define REGS 8 #endif #endif #ifdef ATOMIC #define ATOM 1 #else #define ATOM 0 #endif #define WARP_SIZE 32 #define PRINT 0 // Dynamic allocation of runtime workgroup id __device__ int dynamic_wg_id(volatile unsigned int *flags, const int num_flags){ __shared__ int gid_; if (threadIdx.x == 0) gid_ = atomicAdd((unsigned int*)&flags[num_flags + 1], 1); __syncthreads(); int my_s = gid_; return my_s; } // Set global synchronization (regular DS) __device__ void ds_sync(volatile unsigned int *flags, const int my_s){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} atomicOr((unsigned int*)&flags[my_s + 1], 1); } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} flags[my_s + 1] = 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS) __device__ void ds_sync_irregular(volatile unsigned int *flags, const int my_s, int *count){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags[my_s], 0) == 0){} int flag = flags[my_s]; atomicAdd((unsigned int*)&flags[my_s + 1], flag + *count); *count = flag - 1; } #else if (threadIdx.x == 0){ while (flags[my_s] == 0){} int flag = flags[my_s]; flags[my_s + 1] = flag + *count; *count = flag - 1; } #endif __syncthreads(); } // Set global synchronization (irregular DS Partition) __device__ void ds_sync_irregular_partition(volatile unsigned int *flags1, volatile unsigned int *flags2, const int my_s, int *count1, int *count2){ #if ATOM if (threadIdx.x == 0){ while (atomicOr((unsigned int*)&flags1[my_s], 0) == 0){} int flag2 = flags2[my_s]; atomicAdd((unsigned int*)&flags2[my_s + 1], flag2 + *count); int flag1 = flags1[my_s]; atomicAdd((unsigned int*)&flags1[my_s + 1], flag1 + *count); *count1 = flag1 - 1; *count2 = flag2 - 1; } #else if (threadIdx.x == 0){ while (flags1[my_s] == 0){} int flag2 = flags2[my_s]; flags2[my_s + 1] = flag2 + *count2; int flag1 = flags1[my_s]; flags1[my_s + 1] = flag1 + *count1; *count1 = flag1 - 1; *count2 = flag2 - 1; } #endif __syncthreads(); } // Reduction kernel (CUDA SDK reduce6) template __device__ void reduction(S *count, S local_cnt){ __shared__ S sdata[L_DIM]; unsigned int tid = threadIdx.x; S mySum = local_cnt; // each runtime puts its local sum into shared memory sdata[tid] = local_cnt; __syncthreads(); // do reduction in shared mem if ((blockDim.x >= 1024) && (tid < 512)){ sdata[tid] = mySum = mySum + sdata[tid + 512]; } __syncthreads(); if ((blockDim.x >= 512) && (tid < 256)){ sdata[tid] = mySum = mySum + sdata[tid + 256]; } __syncthreads(); if ((blockDim.x >= 256) && (tid < 128)){ sdata[tid] = mySum = mySum + sdata[tid + 128]; } __syncthreads(); if ((blockDim.x >= 128) && (tid < 64)){ sdata[tid] = mySum = mySum + sdata[tid + 64]; } __syncthreads(); #if (__CUDA_ARCH__ >= 300 ) if ( tid < 32 ){ // Fetch final intermediate sum from 2nd warp if (blockDim.x >= 64) mySum += sdata[tid + 32]; // Reduce final warp using shuffle #pragma unroll for (int offset = WARP_SIZE/2; offset > 0; offset /= 2){ //mySum += __shfl_down(mySum, offset); mySum += __shfl_xor(mySum, offset); } } #else // fully unroll reduction within a single warp if ((blockDim.x >= 64) && (tid < 32)){ sdata[tid] = mySum = mySum + sdata[tid + 32]; } __syncthreads(); if ((blockDim.x >= 32) && (tid < 16)){ sdata[tid] = mySum = mySum + sdata[tid + 16]; } __syncthreads(); if ((blockDim.x >= 16) && (tid < 8)){ sdata[tid] = mySum = mySum + sdata[tid + 8]; } __syncthreads(); if ((blockDim.x >= 8) && (tid < 4)){ sdata[tid] = mySum = mySum + sdata[tid + 4]; } __syncthreads(); if ((blockDim.x >= 4) && (tid < 2)){ sdata[tid] = mySum = mySum + sdata[tid + 2]; } __syncthreads(); if ((blockDim.x >= 2) && ( tid < 1)){ sdata[tid] = mySum = mySum + sdata[tid + 1]; } __syncthreads(); #endif // write result for this block to global mem if (tid == 0) *count = mySum; } // Binary prefix-sum (GPU Computing Gems) __device__ inline int lane_id(void) { return threadIdx.x % WARP_SIZE; } __device__ inline int warp_id(void) { return threadIdx.x / WARP_SIZE; } __device__ unsigned int warp_prefix_sums(bool p){ unsigned int b = __ballot(p); return __popc(b & ((1 << lane_id()) - 1)); } __device__ int warp_scan(int val, volatile int *s_data){ #if (__CUDA_ARCH__ < 300 ) int idx = 2 * threadIdx.x - (threadIdx.x & (WARP_SIZE - 1)); s_data[idx] = 0; idx += WARP_SIZE; int t = s_data[idx] = val; s_data[idx] = t = t + s_data[idx - 1]; s_data[idx] = t = t + s_data[idx - 2]; s_data[idx] = t = t + s_data[idx - 4]; s_data[idx] = t = t + s_data[idx - 8]; s_data[idx] = t = t + s_data[idx - 16]; return s_data[idx - 1]; #else int x = val; #pragma unroll for(int offset = 1; offset < 32; offset <<= 1){ // From GTC: Kepler shuffle tips and tricks: #if 0 int y = __shfl_up(x, offset); if(lane_id() >= offset) x += y; #else asm volatile("{" " .reg .s32 r0;" " .reg .pred p;" " shfl.up.b32 r0|p, %0, %1, 0x0;" " @p add.s32 r0, r0, %0;" " mov.s32 %0, r0;" "}" : "+r"(x) : "r"(offset)); #endif } return x - val; #endif } __device__ int block_binary_prefix_sums(int* count, int x){ __shared__ int sdata[L_DIM]; // A. Exclusive scan within each warp int warpPrefix = warp_prefix_sums(x); // B. Store in shared memory if(lane_id() == WARP_SIZE - 1) sdata[warp_id()] = warpPrefix + x; __syncthreads(); // C. One warp scans in shared memory if(threadIdx.x < WARP_SIZE) sdata[threadIdx.x] = warp_scan(sdata[threadIdx.x], sdata); __syncthreads(); // D. Each runtime calculates it final value int thread_out_element = warpPrefix + sdata[warp_id()]; int output = thread_out_element + *count; __syncthreads(); if(threadIdx.x == blockDim.x - 1) *count += (thread_out_element + x); return output; } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/gpu/kernel.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ __device__ T warp_up(T reg, int delta){ __shared__ volatile T R[L_DIM]; R[threadIdx.x] = reg; return (lane_id() - delta >= 0 ? R[threadIdx.x - delta] : 0); } __device__ T __shuffle_up(T* matrix, int my_s, int pos, T regi, int i){ #if (__CUDA_ARCH__ >= 300 ) T p = __shfl_up(regi, 1); #else T p = warp_up(regi, 1); #endif if(lane_id() == 0 && i > 0) p = matrix[pos - 1]; if(lane_id() == 0 && threadIdx.x != 0 && i == 0) p = matrix[pos - 1]; if(my_s > 0 && threadIdx.x == 0 && i == 0) p = matrix[pos - 1]; if(my_s == 0 && threadIdx.x == 0 && i == 0) p = -1; return p; } __global__ void unique(T *matrix_out, T *matrix, int size, volatile unsigned int *flags) { __shared__ int count; // Counter for number of non-zero elements per block const int num_flags = size % (blockDim.x * REGS) == 0 ? size / (blockDim.x * REGS) : size / (blockDim.x * REGS) + 1; // Dynamic allocation of runtime workgroup id if (threadIdx.x == 0) count = 0; const int my_s = dynamic_wg_id(flags, num_flags); int local_cnt = 0; // Declare on-chip memory T reg[REGS]; int pos = my_s * REGS * blockDim.x + threadIdx.x; // Load in on-chip memory #pragma unroll for (int j = 0; j < REGS; j++){ if (pos < size){ reg[j] = matrix[pos]; if(reg[j] != __shuffle_up(matrix, my_s, pos, reg[j], j)) local_cnt++; else reg[j] = -1; } else reg[j] = -1; pos += blockDim.x; } reduction(&count, local_cnt); // Set global synch ds_sync_irregular(flags, my_s, &count); // Store to global memory #pragma unroll for (int j = 0; j < REGS; j++){ pos = block_binary_prefix_sums(&count, reg[j] >= 0); if (reg[j] >= 0){ matrix_out[pos] = reg[j]; } } } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/baselines/gpu/unique.cu ================================================ /*************************************************************************** *cr *cr (C) Copyright 2015 The Board of Trustees of the *cr University of Illinois *cr All Rights Reserved *cr ***************************************************************************/ /* In-Place Data Sliding Algorithms for Many-Core Architectures, presented in ICPP’15 Copyright (c) 2015 University of Illinois at Urbana-Champaign. All rights reserved. Permission to use, copy, modify and distribute this software and its documentation for educational purpose is hereby granted without fee, provided that the above copyright notice and this permission notice appear in all copies of this software and that you do not sell the software. THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,EXPRESS, IMPLIED OR OTHERWISE. Authors: Juan Gómez-Luna (el1goluj@uco.es, gomezlun@illinois.edu), Li-Wen Chang (lchang20@illinois.edu) */ #include "ds.h" #include "kernel.cu" // Sequential CPU version void cpu_unique(T* output, T* input, int elements){ int j = 0; output[j] = input[j]; j++; for (int i = 1; i < elements; i++){ if (input[i] != input[i-1]){ output[j] = input[i]; j++; } } } int main(int argc, char **argv){ // Syntax verification if (argc != 4) { printf("Wrong format\n"); printf("Syntax: %s \n",argv[0]); exit(1); } int device = atoi(argv[1]); int input = atoi(argv[2]); int numElements = atoi(argv[3]); size_t size = numElements * sizeof(T); // Set device cudaDeviceProp device_properties; cudaGetDeviceProperties(&device_properties,device); cudaSetDevice(device); printf("DS Unique on %s\n", device_properties.name); printf("Thread block size = %d\n", L_DIM); printf("Coarsening factor = %d\n", REGS); #ifdef FLOAT printf("Single precision array: %d elements\n", numElements); #elif INT printf("Integer array: %d elements\n", numElements); #else printf("Double precision array: %d elements\n", numElements); #endif // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; float time2 = 0; // Allocate the host input vector A T *h_A = (T*)malloc(size); // Allocate the host output vectors T *h_B = (T*)malloc(size); T *h_C = (T*)malloc(size); // Allocate the device input vector A T *d_A = NULL; cudaMalloc((void **)&d_A, size); #define WARMUP 0 #define REP 1 int value1 = 0; int value2 = 1; int value3 = 2; int value4 = 3; unsigned int flagM = 0; for(int iteration = 0; iteration < REP+WARMUP; iteration++){ // Initialize the host input vectors srand(2014); for(int i = 0; i < numElements; i++){ h_A[i] = value1; if(i >= numElements/4 && i < numElements/2) h_A[i] = value2; if(i >= numElements/2 && i < 3*numElements/4) h_A[i] = value3; if(i >= 3*numElements/4 && i < numElements) h_A[i] = value4; } int M = (numElements * input)/100; int m = M; while(m>0){ int x = (int)(numElements*(((float)rand()/(float)RAND_MAX))); if(h_A[x]==value1 || h_A[x]==value2 || h_A[x]==value3 || h_A[x]==value4){ h_A[x] = x+2; m--; } } #if PRINT printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_A+i)); } printf("\n"); #endif // Copy the host input vector A in host memory to the device input vector in device memory cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice); int ldim = L_DIM; // Atomic flags unsigned int* d_flags = NULL; int num_flags = numElements % (ldim * REGS) == 0 ? numElements / (ldim * REGS) : numElements / (ldim * REGS) + 1; unsigned int *flags = (unsigned int *)calloc(sizeof(unsigned int), num_flags + 2); flags[0] = 1; flags[num_flags + 1] = 0; cudaMalloc((void **)&d_flags, (num_flags + 2) * sizeof(unsigned int)); cudaMemcpy(d_flags, flags, (num_flags + 2) * sizeof(unsigned int), cudaMemcpyHostToDevice); free(flags); // Number of work-groups/runtime blocks int num_wg = num_flags; // Start timer cudaEventRecord( start, 0 ); // Kernel launch unique<<>>(d_A, d_A, numElements, d_flags); cudaMemcpy(&flagM, d_flags + num_flags, sizeof(unsigned int), cudaMemcpyDeviceToHost); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); if(iteration >= WARMUP) time2 += time1; if(iteration == REP+WARMUP-1){ float timer = time2 / REP; double bw = (double)((numElements + flagM) * sizeof(T)) / (double)(timer * 1000000.0); printf("Execution time = %f ms, Throughput = %f GB/s\n", timer, bw); } // Free flags cudaFree(d_flags); } // Copy to host memory cudaMemcpy(h_B, d_A, size, cudaMemcpyDeviceToHost); // CPU execution for comparison cpu_unique(h_C, h_A, numElements); // Verify that the result vector is correct #if PRINT for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_B+i)); } printf("\n"); for(int i = 0; i < numElements; ++i){ printf("%d ",*(h_C+i)); } printf("\n"); #endif for (int i = 0; i < flagM - 1; ++i){ if (h_B[i] != h_C[i]){ fprintf(stderr, "Result verification failed at element %d!\n", i); exit(EXIT_FAILURE); } } printf("Test PASSED\n"); // Free device global memory cudaFree(d_A); cudaEventDestroy(start); cudaEventDestroy(stop); // Free host memory free(h_A); free(h_B); free(h_C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/dpu/CMakeLists.txt ================================================ SET(BL 10) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/UNI/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL}") file(GLOB_RECURSE SRCS *.c) add_executable(UNI_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/dpu/task.c ================================================ /* * Unique with multiple tasklets * */ #include #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; __host dpu_results_t DPU_RESULTS[NR_TASKLETS]; // Array for communication between adjacent tasklets uint32_t message[NR_TASKLETS]; T message_value[NR_TASKLETS]; uint32_t message_offset[NR_TASKLETS]; uint32_t message_partial_count; T message_last_from_last; // UNI in each tasklet unsigned int __attribute__ ((noinline)) unique(T *output, T *input){ unsigned int pos = 0; output[pos] = input[pos]; pos++; #pragma unroll for(unsigned int j = 1; j < REGS; j++) { if(input[j] != input[j - 1]) { output[pos] = input[j]; pos++; } } return pos; } // Handshake with adjacent tasklets uint3 __attribute__ ((noinline)) handshake_sync(T *output, unsigned int l_count, unsigned int tasklet_id){ unsigned int p_count, o_count, offset; // Wait and read message if(tasklet_id != 0){ handshake_wait_for(tasklet_id - 1); p_count = message[tasklet_id]; offset = (message_value[tasklet_id] == output[0])?1:0; o_count = message_offset[tasklet_id]; } else{ p_count = 0; offset = (message_last_from_last == output[0])?1:0; o_count = 0; } // Write message and notify if(tasklet_id < NR_TASKLETS - 1){ message[tasklet_id + 1] = p_count + l_count; message_value[tasklet_id + 1] = output[l_count - 1]; message_offset[tasklet_id + 1] = o_count + offset; handshake_notify(); } uint3 result = {p_count, o_count, offset}; return result; } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); dpu_results_t *result = &DPU_RESULTS[tasklet_id]; uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); // Initialize shared variable if(tasklet_id == NR_TASKLETS - 1){ message_partial_count = 0; message_last_from_last = 0xFFFFFFFF; // A value that is not in the input array } // Barrier barrier_wait(&my_barrier); unsigned int i = 0; // Iteration count for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, BLOCK_SIZE); // UNI in each tasklet unsigned int l_count = unique(cache_B, cache_A); // In-place or out-of-place? // Sync with adjacent tasklets uint3 po_count = handshake_sync(cache_B, l_count, tasklet_id); // Write cache to current MRAM block mram_write(&cache_B[po_count.z], (__mram_ptr void*)(mram_base_addr_B + (message_partial_count + po_count.x - po_count.y) * sizeof(T)), l_count * sizeof(T)); // First if(tasklet_id == 0 && i == 0){ result->first = cache_B[0]; } // Total count in this DPU if(tasklet_id == NR_TASKLETS - 1){ message_last_from_last = cache_B[l_count - 1]; result->last = cache_B[l_count - 1]; result->t_count = message_partial_count + po_count.x + l_count - po_count.y - po_count.z; message_partial_count = result->t_count; } // Barrier barrier_wait(&my_barrier); i++; } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/host/app.c ================================================ #include #include #include #include #include #include #include #include #include struct dpu_arguments_t { int size; int kernel; }; struct dpu_results_t{ long t_count; long first; long last; }; #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 1024 #define REGS 128 void read_input(long* A, int nr_elements, int nr_elements_round) { for (int i = 0; i < nr_elements; i++) { A[i] = i%2==0?i:i+1; } for (int i = nr_elements; i < nr_elements_round; i++) { A[i] = A[nr_elements - 1]; } } int unique_host(long* C, long* A, int nr_elements) { int pos = 0; C[pos] = A[pos]; pos++; for(int i = 1; i < nr_elements; i++) { if(A[i] != A[i-1]) { C[pos] = A[i]; pos++; } } return pos; } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { long* A; long* C; long* C2; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; dpu_alloc(nr_of_dpus, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int i = 0; int accum = 0; int total_count = 0; int input_size = DATA_PREP_PARAMS; int input_size_dpu_ = divceil(input_size, nr_of_dpus); int input_size_dpu_round = (input_size_dpu_ % (NUM_TASKLETS * REGS) != 0) ? roundup(input_size_dpu_, (NUM_TASKLETS * REGS)) : input_size_dpu_; A = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); C2 = malloc(input_size_dpu_round * nr_of_dpus * sizeof(long)); long *bufferA = A; long *bufferC = C2; read_input(A, input_size, input_size_dpu_round * nr_of_dpus); total_count = unique_host(C, A, input_size); int input_size_dpu = input_size_dpu_round; int kernel = 0; struct dpu_arguments_t* input_arguments = malloc(sizeof(struct dpu_arguments_t)); input_arguments->size = input_size_dpu * sizeof(long); input_arguments->kernel = kernel; i = 0; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, input_arguments); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "DPU_INPUT_ARGUMENTS", 0, sizeof(struct dpu_arguments_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &bufferA[input_size_dpu * i]); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, input_size_dpu * sizeof(long), DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); struct dpu_results_t* results = malloc(nr_of_dpus * sizeof(struct dpu_results_t)); int* results_scan = malloc(nr_of_dpus * sizeof(int)); int* offset = malloc(nr_of_dpus * sizeof(int)); int* offset_scan = malloc(nr_of_dpus * sizeof(int)); i = 0; accum = 0; struct dpu_results_t* results_retrieve = malloc(nr_of_dpus * NUM_TASKLETS * sizeof(struct dpu_results_t)); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &results_retrieve[i * NUM_TASKLETS]); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, "DPU_RESULTS", 0, NUM_TASKLETS * sizeof(struct dpu_results_t), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { for (int each_tasklet = 0; each_tasklet < NUM_TASKLETS; each_tasklet++) { if(each_tasklet == 0){ results[i].first = results_retrieve[i * NUM_TASKLETS + each_tasklet].first; } if(each_tasklet == NUM_TASKLETS - 1){ results[i].t_count = results_retrieve[i * NUM_TASKLETS + each_tasklet].t_count; results[i].last = results_retrieve[i * NUM_TASKLETS + each_tasklet].last; } } if(i != 0){ if(results[i].first == results[i - 1].last) { offset[i] = 1; } offset_scan[i] += offset[i]; } int temp = results[i].t_count - offset[i]; results_scan[i] = accum; accum += temp; } i = 0; DPU_FOREACH (dpu_set, dpu, i) { dpu_copy_from(dpu, DPU_MRAM_HEAP_POINTER_NAME, input_size_dpu * sizeof(long), &bufferC[results_scan[i] - offset_scan[i]], results[i].t_count * sizeof(long)); } free(results_scan); free(offset); free(offset_scan); int status = 1; if(accum != total_count) { status = 0; break; } for (i = 0; i < accum; i++) { if(C[i] != bufferC[i]){ status = 0; break; } } assert(status); free(A); free(C); free(C2); dpu_free(dpu_set); return status ? 0 : -1; } ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/support/common.h ================================================ #ifndef _COMMON_H_ #define _COMMON_H_ // Data type #define T int64_t #define REGS (BLOCK_SIZE >> 3) // 64 bits // Structures used by both the host and the dpu to communicate information typedef struct { uint32_t size; enum kernels { kernel1 = 0, nr_kernels = 1, } kernel; } dpu_arguments_t; typedef struct { uint32_t t_count; T first; T last; } dpu_results_t; // Transfer size between MRAM and WRAM #ifdef BL #define BLOCK_SIZE_LOG2 BL #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #else #define BLOCK_SIZE_LOG2 8 #define BLOCK_SIZE (1 << BLOCK_SIZE_LOG2) #define BL BLOCK_SIZE_LOG2 #endif typedef struct{unsigned int x; unsigned int y; unsigned int z;} uint3; #ifndef ENERGY #define ENERGY 0 #endif #define PRINT 0 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_RESET "\x1b[0m" #define divceil(n, m) (((n)-1) / (m) + 1) #define roundup(n, m) ((n / m) * m + m) #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/support/params.h ================================================ #ifndef _PARAMS_H_ #define _PARAMS_H_ #include "common.h" typedef struct Params { unsigned int input_size; int n_warmup; int n_reps; int exp; }Params; static void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=3932160 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 3932160; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/UNI/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[7]; struct timeval stopTime[7]; double time[7]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/CMakeLists.txt ================================================ # add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/Makefile ================================================ DPU_DIR := dpu HOST_DIR := host BUILDDIR ?= bin NR_TASKLETS ?= 16 BL ?= 10 NR_DPUS ?= 1 TYPE ?= INT32 ENERGY ?= 0 define conf_filename ${BUILDDIR}/.NR_DPUS_$(1)_NR_TASKLETS_$(2)_BL_$(3)_TYPE_$(4).conf endef CONF := $(call conf_filename,${NR_DPUS},${NR_TASKLETS},${BL},${TYPE}) HOST_TARGET := ${BUILDDIR}/host_code DPU_TARGET := ${BUILDDIR}/dpu_code COMMON_INCLUDES := support HOST_SOURCES := $(wildcard ${HOST_DIR}/*.c) DPU_SOURCES := $(wildcard ${DPU_DIR}/*.c) .PHONY: all clean test __dirs := $(shell mkdir -p ${BUILDDIR}) COMMON_FLAGS := -w -I${COMMON_INCLUDES} HOST_FLAGS := ${COMMON_FLAGS} -std=c11 -O3 `dpu-pkg-config --cflags --libs dpu` -DNR_TASKLETS=${NR_TASKLETS} -DNR_DPUS=${NR_DPUS} -DBL=${BL} -D${TYPE} -DENERGY=${ENERGY} DPU_FLAGS := ${COMMON_FLAGS} -O2 -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE} all: ${HOST_TARGET} ${DPU_TARGET} ${CONF}: $(RM) $(call conf_filename,*,*) touch ${CONF} ${HOST_TARGET}: ${HOST_SOURCES} ${COMMON_INCLUDES} ${CONF} $(CC) -o ${HOST_TARGET}.bin ${HOST_SOURCES} ${HOST_FLAGS} $(CC) -S -o ${HOST_TARGET}.S ${HOST_SOURCES} ${HOST_FLAGS} ${DPU_TARGET}: ${DPU_SOURCES} ${COMMON_INCLUDES} ${CONF} dpu-upmem-dpurte-clang ${DPU_FLAGS} -o $@ ${DPU_SOURCES} dpu-upmem-dpurte-clang -S ${DPU_FLAGS} -o ${DPU_TARGET}.S ${DPU_SOURCES} clean: $(RM) -r $(BUILDDIR) test: all ./${HOST_TARGET} ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/cpu/Makefile ================================================ all: gcc -o va -fopenmp app_baseline.c clean: rm va ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/cpu/README ================================================ Vector addition (VA) Compilation instructions make Execution instructions ./va -t 4 ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/cpu/app_baseline.c ================================================ /** * @file app.c * @brief Template for a Host Application Source File. * */ #include #include #include #include #include #include #include #include #include #include "../../support/timer.h" static int32_t *A; static int32_t *B; static int32_t *C; static int32_t *C2; /** * @brief creates a "test file" by filling a buffer of 64MB with pseudo-random values * @param nr_elements how many 32-bit elements we want the file to be * @return the buffer address */ void *create_test_file(unsigned int nr_elements) { srand(0); printf("nr_elements\t%u\t", nr_elements); A = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); B = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); C = (uint32_t*) malloc(nr_elements * sizeof(uint32_t)); for (int i = 0; i < nr_elements; i++) { A[i] = (int) (rand()); B[i] = (int) (rand()); } } /** * @brief compute output in the host */ static void vector_addition_host(unsigned int nr_elements, int t) { omp_set_num_threads(t); #pragma omp parallel for for (int i = 0; i < nr_elements; i++) { C[i] = A[i] + B[i]; } } // Params --------------------------------------------------------------------- typedef struct Params { int input_size; int n_warmup; int n_reps; int n_threads; }Params; void usage() { fprintf(stderr, "\nUsage: ./program [options]" "\n" "\nGeneral options:" "\n -h help" "\n -t # of threads (default=8)" "\n -w # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=8M elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 16777216; p.n_warmup = 1; p.n_reps = 3; p.n_threads = 5; int opt; while((opt = getopt(argc, argv, "hi:w:e:t:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 't': p.n_threads = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(p.n_threads > 0 && "Invalid # of ranks!"); return p; } /** * @brief Main of the Host Application. */ int main(int argc, char **argv) { struct Params p = input_params(argc, argv); const unsigned int file_size = p.input_size; // Create an input file with arbitrary data. create_test_file(file_size); Timer timer; start(&timer, 0, 0); vector_addition_host(file_size, p.n_threads); stop(&timer, 0); printf("Kernel "); print(&timer, 0, 1); printf("\n"); free(A); free(B); free(C); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/gpu/Makefile ================================================ all: /usr/local/cuda/bin/nvcc vec_add.cu -I/usr/local/cuda/include -lm -o va clean: rm va ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/gpu/README ================================================ Vector addition (VA) Compilation instructions make Execution instructions ./va ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/baselines/gpu/vec_add.cu ================================================ /* File: vec_add.cu * Purpose: Implement vector addition on a gpu using cuda * * Compile: nvcc [-g] [-G] -o vec_add vec_add.cu * Run: ./vec_add */ #include #include #include #include __global__ void Vec_add(unsigned int x[], unsigned int y[], unsigned int z[], int n) { int thread_id = blockIdx.x * blockDim.x + threadIdx.x; if (thread_id < n){ z[thread_id] = x[thread_id] + y[thread_id]; } } int main(int argc, char* argv[]) { int n, m; unsigned int *h_x, *h_y, *h_z; unsigned int *d_x, *d_y, *d_z; size_t size; /* Define vector length */ n = 2621440; m = 320; size = m * n * sizeof(unsigned int); // Allocate memory for the vectors on host memory. h_x = (unsigned int*) malloc(size); h_y = (unsigned int*) malloc(size); h_z = (unsigned int*) malloc(size); for (int i = 0; i < n * m; i++) { h_x[i] = i+1; h_y[i] = n-i; } printf("Input size = %d\n", n * m); // Print original vectors. /*printf("h_x = "); for (int i = 0; i < m; i++){ printf("%u ", h_x[i]); } printf("\n\n"); printf("h_y = "); for (int i = 0; i < m; i++){ printf("%u ", h_y[i]); } printf("\n\n");*/ // Event creation cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); float time1 = 0; /* Allocate vectors in device memory */ cudaMalloc(&d_x, size); cudaMalloc(&d_y, size); cudaMalloc(&d_z, size); /* Copy vectors from host memory to device memory */ cudaMemcpy(d_x, h_x, size, cudaMemcpyHostToDevice); cudaMemcpy(d_y, h_y, size, cudaMemcpyHostToDevice); // Start timer cudaEventRecord( start, 0 ); /* Kernel Call */ Vec_add<<<(n * m) / 256, 256>>>(d_x, d_y, d_z, n * m); // End timer cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &time1, start, stop ); cudaMemcpy(h_z, d_z, size, cudaMemcpyDeviceToHost); /*printf("The sum is: \n"); for (int i = 0; i < m; i++){ printf("%u ", h_z[i]); } printf("\n");*/ printf("Execution time = %f ms\n", time1); /* Free device memory */ cudaFree(d_x); cudaFree(d_y); cudaFree(d_z); /* Free host memory */ free(h_x); free(h_y); free(h_z); return 0; } /* main */ ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/dpu/CMakeLists.txt ================================================ SET(BL 10) SET(TYPE INT32) set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/VA/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS} -DBL=${BL} -D${TYPE}") file(GLOB_RECURSE SRCS *.c) add_executable(VA_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/dpu/task.c ================================================ /* * Vector addition with multiple tasklets * */ #include #include #include #include #include #include #include #include "../support/common.h" __host dpu_arguments_t DPU_INPUT_ARGUMENTS; // vector_addition: Computes the vector addition of a cached block void __attribute__ ((noinline)) vector_addition(T *bufferB, T *bufferA, unsigned int l_size) { for (unsigned int i = 0; i < l_size; i++){ bufferB[i] += bufferA[i]; } } // Barrier BARRIER_INIT(my_barrier, NR_TASKLETS); extern int main_kernel1(void); int (*kernels[nr_kernels])(void) = {main_kernel1}; int main(void) { // Kernel return kernels[DPU_INPUT_ARGUMENTS.kernel](); } // main_kernel1 int main_kernel1() { unsigned int tasklet_id = me(); #if PRINT printf("tasklet_id = %u\n", tasklet_id); #endif if (tasklet_id == 0){ // Initialize once the cycle counter mem_reset(); // Reset the heap } // Barrier barrier_wait(&my_barrier); uint32_t input_size_dpu_bytes = DPU_INPUT_ARGUMENTS.size; // Input size per DPU in bytes uint32_t input_size_dpu_bytes_transfer = DPU_INPUT_ARGUMENTS.transfer_size; // Transfer input size per DPU in bytes // Address of the current processing block in MRAM uint32_t base_tasklet = tasklet_id << BLOCK_SIZE_LOG2; uint32_t mram_base_addr_A = (uint32_t)DPU_MRAM_HEAP_POINTER; uint32_t mram_base_addr_B = (uint32_t)(DPU_MRAM_HEAP_POINTER + input_size_dpu_bytes_transfer); // Initialize a local cache to store the MRAM block T *cache_A = (T *) mem_alloc(BLOCK_SIZE); T *cache_B = (T *) mem_alloc(BLOCK_SIZE); for(unsigned int byte_index = base_tasklet; byte_index < input_size_dpu_bytes; byte_index += BLOCK_SIZE * NR_TASKLETS){ // Bound checking uint32_t l_size_bytes = (byte_index + BLOCK_SIZE >= input_size_dpu_bytes) ? (input_size_dpu_bytes - byte_index) : BLOCK_SIZE; // Load cache with current MRAM block mram_read((__mram_ptr void const*)(mram_base_addr_A + byte_index), cache_A, l_size_bytes); mram_read((__mram_ptr void const*)(mram_base_addr_B + byte_index), cache_B, l_size_bytes); // Computer vector addition vector_addition(cache_B, cache_A, l_size_bytes >> DIV); // Write cache to current MRAM block mram_write(cache_B, (__mram_ptr void*)(mram_base_addr_B + byte_index), l_size_bytes); } return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/host/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/usr/bin/gcc") set(CMAKE_C_FLAGS "-std=c99 -O3") find_package(PkgConfig REQUIRED) pkg_check_modules(DPU REQUIRED dpu) file(GLOB_RECURSE SRCS *.c) add_executable(VA_host ${SRCS}) target_link_libraries(VA_host ${DPU_LIBRARIES}) target_include_directories(VA_host PUBLIC ${DPU_INCLUDE_DIRS}) target_compile_options(VA_host PUBLIC ${DPU_CFLAGS_OTHER}) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/host/app.c ================================================ #include #include #include #include #include #include #include #include #include struct dpu_arguments_t { int size; int transfer_size; int kernel; }; #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 1024 void read_input(int* A, int* B, int nr_elements) { for (int i = 0; i < nr_elements; i++) { A[i] = i; B[i] = i; } } void vector_addition_host(int* C, int* A, int* B, int nr_elements) { for (int i = 0; i < nr_elements; i++) { C[i] = A[i] + B[i]; } } int roundup(int n, int m) { return ((n / m) * m + m); } int divceil(int n, int m) { return ((n-1) / m + 1); } int main() { int BL = 10; int BLOCK_SIZE_LOG2 = BL; int BLOCK_SIZE = (1 << BLOCK_SIZE_LOG2); int* A; int* B; int* C; int* C2; struct dpu_set_t dpu_set; struct dpu_set_t dpu; int nr_of_dpus = NUM_DPUS; int input_size = DATA_PREP_PARAMS; dpu_alloc(nr_of_dpus, NULL, &dpu_set); dpu_load(dpu_set, DPU_BINARY, NULL); int i = 0; int input_size_8bytes = ((input_size * sizeof(int)) % 8) != 0 ? roundup(input_size, 8) : input_size; int input_size_dpu = divceil(input_size, nr_of_dpus); int input_size_dpu_8bytes = ((input_size_dpu * sizeof(int)) % 8) != 0 ? roundup(input_size_dpu, 8) : input_size_dpu; A = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); B = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); C = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); C2 = malloc(input_size_dpu_8bytes * nr_of_dpus * sizeof(int)); int *bufferA = A; int *bufferB = B; int *bufferC = C2; read_input(A, B, input_size); vector_addition_host(C, A, B, input_size); int kernel = 0; struct dpu_arguments_t* input_arguments = malloc(sizeof(struct dpu_arguments_t) * nr_of_dpus); for(i=0; i # of untimed warmup iterations (default=1)" "\n -e # of timed repetition iterations (default=3)" "\n -x Weak (0) or strong (1) scaling (default=0)" "\n" "\nBenchmark-specific options:" "\n -i input size (default=2621440 elements)" "\n"); } struct Params input_params(int argc, char **argv) { struct Params p; p.input_size = 2621440; p.n_warmup = 1; p.n_reps = 3; p.exp = 0; int opt; while((opt = getopt(argc, argv, "hi:w:e:x:")) >= 0) { switch(opt) { case 'h': usage(); exit(0); break; case 'i': p.input_size = atoi(optarg); break; case 'w': p.n_warmup = atoi(optarg); break; case 'e': p.n_reps = atoi(optarg); break; case 'x': p.exp = atoi(optarg); break; default: fprintf(stderr, "\nUnrecognized option!\n"); usage(); exit(0); } } assert(NR_DPUS > 0 && "Invalid # of dpus!"); return p; } #endif ================================================ FILE: golang_vm/uPIMulator/benchmark/VA/support/timer.h ================================================ /* * Copyright (c) 2016 University of Cordoba and University of Illinois * All rights reserved. * * Developed by: IMPACT Research Group * University of Cordoba and University of Illinois * http://impact.crhc.illinois.edu/ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * with the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * > Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * > Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * > Neither the names of IMPACT Research Group, University of Cordoba, * University of Illinois nor the names of its contributors may be used * to endorse or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH * THE SOFTWARE. * */ #include typedef struct Timer{ struct timeval startTime[4]; struct timeval stopTime[4]; double time[4]; }Timer; void start(Timer *timer, int i, int rep) { if(rep == 0) { timer->time[i] = 0.0; } gettimeofday(&timer->startTime[i], NULL); } void stop(Timer *timer, int i) { gettimeofday(&timer->stopTime[i], NULL); timer->time[i] += (timer->stopTime[i].tv_sec - timer->startTime[i].tv_sec) * 1000000.0 + (timer->stopTime[i].tv_usec - timer->startTime[i].tv_usec); } void print(Timer *timer, int i, int REP) { printf("Time (ms): %f\t", timer->time[i] / (1000 * REP)); } ================================================ FILE: golang_vm/uPIMulator/benchmark/VA_SIMPLE/CMakeLists.txt ================================================ # add_subdirectory(host) add_subdirectory(dpu) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA_SIMPLE/dpu/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-w -I/root/uPIMulator/benchmark/VA/support -O2 -S -DNR_TASKLETS=${NR_TASKLETS}") file(GLOB_RECURSE SRCS *.c) add_executable(VA_SIMPLE_device ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA_SIMPLE/dpu/task.c ================================================ #include #include #include #include __host int size_per_dpu; BARRIER_INIT(my_barrier, NR_TASKLETS); void vector_addition(int *A, int *B, int *C, int size_per_tasklet) { for (int i = 0; i < size_per_tasklet / sizeof(int); i++) { C[i] = A[i] + B[i]; } } int main() { int tasklet_id = me(); if (tasklet_id == 0) { mem_reset(); } barrier_wait(&my_barrier); int size_per_tasklet = size_per_dpu / NR_TASKLETS; int *A_mram = (int *)(DPU_MRAM_HEAP_POINTER + tasklet_id * size_per_tasklet); int *B_mram = (int *)(DPU_MRAM_HEAP_POINTER + size_per_dpu + tasklet_id * size_per_tasklet); int *C_mram = (int *)(DPU_MRAM_HEAP_POINTER + 2 * size_per_dpu + tasklet_id * size_per_tasklet); int *A_wram = (int *)mem_alloc(size_per_tasklet); int *B_wram = (int *)mem_alloc(size_per_tasklet); int *C_wram = (int *)mem_alloc(size_per_tasklet); mram_read((__mram_ptr void *)A_mram, A_wram, size_per_tasklet); mram_read((__mram_ptr void *)B_mram, B_wram, size_per_tasklet); vector_addition(A_wram, B_wram, C_wram, size_per_tasklet); mram_write(C_wram, (__mram_ptr void *)C_mram, size_per_tasklet); return 0; } ================================================ FILE: golang_vm/uPIMulator/benchmark/VA_SIMPLE/host/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/usr/bin/gcc") set(CMAKE_C_FLAGS "-std=c99 -O3") find_package(PkgConfig REQUIRED) pkg_check_modules(DPU REQUIRED dpu) file(GLOB_RECURSE SRCS *.c) add_executable(VA_SIMPLE_host ${SRCS}) target_link_libraries(VA_SIMPLE_host ${DPU_LIBRARIES}) target_include_directories(VA_SIMPLE_host PUBLIC ${DPU_INCLUDE_DIRS}) target_compile_options(VA_SIMPLE_host PUBLIC ${DPU_CFLAGS_OTHER}) ================================================ FILE: golang_vm/uPIMulator/benchmark/VA_SIMPLE/host/app.c ================================================ #include #include #include #define VECTOR_SIZE 1024 #define NUM_DPUS 1 #define NUM_TASKLETS 1 #define DATA_PREP_PARAMS 1024 struct vector_t { int size; int* data; }; struct vector_t* vector_init(int size); void vector_prep(struct vector_t* vector); void vector_add(struct vector_t* a, struct vector_t *b, struct vector_t* c); void vector_equal(struct vector_t* a, struct vector_t* b); int main() { struct dpu_set_t dpu_set; struct dpu_set_t dpu; dpu_alloc(NUM_DPUS, nullptr, &dpu_set); dpu_load(dpu_set, "../device/device", nullptr); struct vector_t *A = vector_init(VECTOR_SIZE); struct vector_t *B = vector_init(VECTOR_SIZE); struct vector_t *C_host = vector_init(VECTOR_SIZE); struct vector_t *C_device = vector_init(VECTOR_SIZE); vector_prep(A); vector_prep(B); vector_add(A, B, C_host); int size_per_dpu = (VECTOR_SIZE / NUM_DPUS) * sizeof(int); int i; DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &size_per_dpu); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, "size_per_dpu", 0, sizeof(int), DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &(A->data[(size_per_dpu / sizeof(int)) * i])); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, 0, size_per_dpu, DPU_XFER_DEFAULT); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &(B->data[(size_per_dpu / sizeof(int)) * i])); } dpu_push_xfer(dpu_set, DPU_XFER_TO_DPU, DPU_MRAM_HEAP_POINTER_NAME, size_per_dpu, size_per_dpu, DPU_XFER_DEFAULT); dpu_launch(dpu_set, DPU_SYNCHRONOUS); DPU_FOREACH(dpu_set, dpu, i) { dpu_prepare_xfer(dpu, &(C_device->data[(size_per_dpu / sizeof(int)) * i])); } dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, DPU_MRAM_HEAP_POINTER_NAME, 2 * size_per_dpu, size_per_dpu, DPU_XFER_DEFAULT); vector_equal(C_host, C_device); return 0; } struct vector_t* vector_init(int size) { struct vector_t* vector = malloc(sizeof(struct vector_t)); vector->size = size; vector->data = malloc(VECTOR_SIZE * sizeof(int)); return vector; } void vector_prep(struct vector_t* vector) { for (int i = 0; i < vector->size; i++) { vector->data[i] = i; } } void vector_add(struct vector_t* a, struct vector_t* b, struct vector_t* c) { assert(a->size == b->size); assert(a->size == c->size); for (int i = 0; i < c->size; i++) { c->data[i] = a->data[i] + b->data[i]; } } void vector_equal(struct vector_t *a, struct vector_t *b) { assert(a->size == b->size); for (int i = 0; i < a->size; i++) { assert(a->data[i] == b->data[i]); } } ================================================ FILE: golang_vm/uPIMulator/benchmark/build.py ================================================ import os import shutil import subprocess import argparse if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--num_dpus", type=int, default=1) parser.add_argument("--num_tasklets", type=int, default=1) args = parser.parse_args() benchmark_dir_path = os.path.dirname(__file__) build_dir_path = os.path.join(benchmark_dir_path, "build") if os.path.exists(build_dir_path): shutil.rmtree(build_dir_path) os.makedirs(build_dir_path) subprocess.run( [ "cmake", "-D", f"NR_DPUS={args.num_dpus}", "-D" f"NR_TASKLETS={args.num_tasklets}", "-S", benchmark_dir_path, "-B", build_dir_path, "-G", "Ninja", ] ) subprocess.run(["ninja", "-C", build_dir_path]) ================================================ FILE: golang_vm/uPIMulator/docker/Dockerfile ================================================ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt update RUN apt install -y git RUN apt install -y wget RUN apt install -y cmake RUN apt install -y ninja-build RUN apt install -y pkg-config RUN apt install -y python3 RUN apt install -y python3-pip # UPMEM SDK WORKDIR /root RUN wget sdk-releases.upmem.com/2023.2.0/ubuntu_22.04/upmem-2023.2.0-Linux-x86_64.tar.gz RUN tar -zxvf upmem-2023.2.0-Linux-x86_64.tar.gz RUN echo "source /root/upmem-2023.2.0-Linux-x86_64/upmem_env.sh" > /root/.bashrc WORKDIR /root/uPIMulator ================================================ FILE: golang_vm/uPIMulator/go.mod ================================================ module uPIMulator go 1.21.5 ================================================ FILE: golang_vm/uPIMulator/script/build.py ================================================ import os import shutil import subprocess if __name__ == "__main__": script_dirpath = os.path.dirname(__file__) build_dirpath = os.path.join(script_dirpath, "..", "build") src_dirpath = os.path.join(script_dirpath, "..", "src") if os.path.exists(build_dirpath): shutil.rmtree(build_dirpath) os.makedirs(build_dirpath) binary_filepath = os.path.join(build_dirpath, "uPIMulator") subprocess.run(["go", "build", "-C", src_dirpath, "-o", binary_filepath]) ================================================ FILE: golang_vm/uPIMulator/script/format.py ================================================ import os import subprocess if __name__ == "__main__": script_dirpath = os.path.dirname(__file__) src_dirpath = os.path.join(script_dirpath, "..", "src") subprocess.run(["gofmt", "-l", src_dirpath]) subprocess.run(["golines", "-w", src_dirpath]) ================================================ FILE: golang_vm/uPIMulator/sdk/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) project(sdk) add_subdirectory(misc) add_subdirectory(stdlib) add_subdirectory(syslib) ================================================ FILE: golang_vm/uPIMulator/sdk/build.py ================================================ import os import shutil import subprocess import argparse if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--num_tasklets", type=int, default=1) args = parser.parse_args() sdk_dir_path = os.path.dirname(__file__) build_dir_path = os.path.join(sdk_dir_path, "build") if os.path.exists(build_dir_path): shutil.rmtree(build_dir_path) os.makedirs(build_dir_path) subprocess.run( [ "cmake", "-D", f"NR_TASKLETS={args.num_tasklets}", "-S", sdk_dir_path, "-B", build_dir_path, "-G", "Ninja", ] ) subprocess.run(["ninja", "-C", build_dir_path]) ================================================ FILE: golang_vm/uPIMulator/sdk/misc/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(misc ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/sdk/misc/accessMramFromDpu.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { // Preconditions: // - MRAM offset is a multiple of 8 // - Buffer size is a multiple of 8 __asm__ volatile(" sd zero, 0, d0\n" // Saving context " sd zero, 8, d2\n" " or r0, zero, 0, ?xnz, . + 2\n" " or r0, r0, 0x2\n" " addc r0, r0, 0\n" " sw zero, 16, r0\n" " lw r0, zero, 20\n" // MRAM offset, must be patched by the Host "resume_start:\n" " lw r1, zero, 24\n" // Buffer size, must be patched by the Host " move r2, 32\n" // Wram offset " move r3, 2048\n" // Transfer size " transfer_loop:\n" " jltu r1, r3, last_transfer\n" " ldma r2, r0, 255\n" // Can be patched by the Host into a SDMA to write MRAM " add r0, r0, r3\n" " add r2, r2, r3\n" " sub r1, r1, r3, true, transfer_loop\n" "last_transfer:\n" " jz r1, end\n" " lsr r3, r1, 3\n" " add r3, r3, -1\n" " lsl_add r2, r2, r3, 24\n" " ldma r2, r0, 0\n" // Can be patched by the Host into a SDMA to write MRAM " add r0, r0, r1\n" "end:\n" " lw r2, zero, 28\n" // Restoring context if needed " jnz r2, . + 2\n" " stop true, resume_start\n" " ld d2, zero, 8\n" " lw r0, zero, 16\n" " add r1, r0, r0\n" " add r0, r0, r1\n" " call zero, r0, . + 1\n" " add r0, zero, 0x00000001; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 0, C = 0 " add r0, mneg, 0x80000001; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 0, C = 1 " add r0, zero, 0x00000000; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 1, C = 0 " add r0, mneg, 0x80000000; ld d0, zero, 0; stop true, 0\n" // ... restore Z = 1, C = 1 ); } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/coreDump.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The "core dump" program, used by debugging processes to fetch each * runtime register and the atomic bits. * The program should be booted once on runtime 0. * * The output in WRAM has the following form: * - byte 0..255 = atomic bits : each bit is stored into an individual byte * - byte 256..2559 = work registers * - byte 2560..2555 = flags * * Only the runtime 0 fills in the atomic bits part of the output. */ #include "restore_carry_and_zero_flag.h" void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0), d0\n" " or r0, zero, 0, ?xnz, no_z_flag\n" " or r0, r0, 0x2\n" " no_z_flag:\n" " addc r0, r0, 0\n" " sw id4, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 12), r0\n" " jeq id, " __STR(NR_THREADS) " - 1, .+2\n" " boot id, 1\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 1), d2\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 2), d4\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 3), d6\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 4), d8\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 5), d10\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 6), d12\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 7), d14\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 8), d16\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 9), d18\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 10), d20\n" " sd id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 11), d22\n" " jnz id, atomic_done\n" " move r0, " __STR(NR_ATOMIC_BITS) " - 1\n" "atomic_loop:\n" " sb r0, 0, 0xFF\n" " acquire r0, 0, nz, atomic_next\n" " sb r0, 0, 0x00\n" " release r0, 0, nz, atomic_next\n" "atomic_next:\n" " add r0, r0, -1, pl, atomic_loop\n" "atomic_done:\n" RESTORE_CARRY_AND_ZERO_FLAG ); /* clang-format on */ } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/crt0.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include __mram_noinit uint8_t __sys_used_mram_end[0]; uint64_t __sys_null_pointer __attribute__((used, section(".data.__sys_zero"))) = 0ULL; uint32_t __lower_data("thread_profiling") thread_profiling[NR_THREADS]; uint32_t perfcounter_end_value; #define DECLARE_STACK(x) \ extern uint32_t __sys_stack_thread_##x; \ extern uint32_t STACK_SIZE_TASKLET_##x; #define SET_STACK_TABLE_PTR(x) \ [x] = { .stack_ptr = (uint32_t)&__sys_stack_thread_##x, .stack_size = (uint32_t)&STACK_SIZE_TASKLET_##x }, __FOR_EACH_THREAD(DECLARE_STACK); thread_stack_t __keep __dma_aligned __SP_TABLE__[NR_THREADS] = { __FOR_EACH_THREAD(SET_STACK_TABLE_PTR) }; __host const volatile uint32_t CLOCKS_PER_SEC; __host const volatile uint32_t error_storage; void __attribute__((naked, used, section(".text.__bootstrap"), no_instrument_function)) __bootstrap() { /* clang-format off */ __asm__ volatile( " jnz id, __sys_start_thread\n" __CONFIG_PERFCOUNTER_ENTRY__ " sd zero, " __STR(__STDOUT_BUFFER_STATE) ", 0\n" " move r23, " __STR(__atomic_end_addr) "\n" "__sys_atomic_bit_clear:\n" " jeq r23, " __STR(__atomic_used_addr) ", __sys_start_thread\n" " release r23, 0, nz, . + 1\n" " add r23, r23, -1, true, __sys_atomic_bit_clear\n" "__sys_start_thread:\n" " jeq id, NR_TASKLETS - 1, . + 2\n" " boot id, 1\n" " ld d22, id8, " __STR(__SP_TABLE__) "\n" " call r23, main\n" ".globl __sys_end\n" "__sys_end:\n" __SAVE_PERFCOUNTER_ENTRY__ " stop true, __sys_end"); /* clang-format on */ } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/dpu.lds ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Default linker script for DPU programs. * The bootstrap sequence is generated by the studio as __bootstrap. * The two DPU memories (IRAM and WRAM) are mapped on two different * "virtual" spaces: * - IRAM: starts at address 0x80000000, which may imply fixups * when loading and debugging of programs * - WRAM: exposed as is at address 0x00000000 * * In addition, the run-time environment information is stored into * a virtual physical space at 0x40000000. */ ENTRY(__bootstrap) MEMORY { iram (rx) : ORIGIN = 0x80000000, LENGTH = 32K mram (wa) : ORIGIN = 0x08000000, LENGTH = 64M wram (wa) : ORIGIN = 0x00000000, LENGTH = 64K atomic (r) : ORIGIN = 0xF0000000, LENGTH = 256 } SECTIONS { /* * Merge every text section into .text. */ .text : { *(.text.__bootstrap) *(.text) *(.text.*) } > iram /* * Atomic bits 'allocator' */ .atomic (NOLOAD) : { __atomic_start_addr = .; . = . + 200; __atomic_used_addr = .; *(.atomic) __atomic_end_addr = .; } > atomic /* * Locate every other section as data. */ .data : { KEEP(*(.data.__sys_zero)) . += MAX(8, .); /* WRAM accessible using loads and stores with immediate 11-bit offsets */ *(.data.immediate_memory .data.immediate_memory.*) HIDDEN(__imm_mem_end = .); ASSERT(__imm_mem_end < 2048, "immediate memory not accessible with 11-bit address") __rodata_start_addr = .; *(.rodata .rodata.*) __rodata_end_addr = .; *(.bss .bss.*) *(COMMON) /* Data that we want to keep even there seems to be no use, * usually because host may need it. */ KEEP(*(.data.__sys_keep)) *(.data .data.*) . = ALIGN(8); } > wram .data.__sys_host : { . = ALIGN(8); KEEP(*(.dpu_host)) } > wram .data.__sys_profiling : { . = ALIGN(4); KEEP(*(.dpu_profiling)) } > wram .data.stacks (NOLOAD) : { ASSERT(NR_TASKLETS >= 0 && NR_TASKLETS <= 24, "NR_TASKLETS should be in the range: [0; 24]") ASSERT(((STACK_SIZE_TASKLET_0 % 8 == 0) && (STACK_SIZE_TASKLET_0 > 0)) || (NR_TASKLETS <= 0 ), "STACK_SIZE_TASKLET_0 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_1 % 8 == 0) && (STACK_SIZE_TASKLET_1 > 0)) || (NR_TASKLETS <= 1 ), "STACK_SIZE_TASKLET_1 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_2 % 8 == 0) && (STACK_SIZE_TASKLET_2 > 0)) || (NR_TASKLETS <= 2 ), "STACK_SIZE_TASKLET_2 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_3 % 8 == 0) && (STACK_SIZE_TASKLET_3 > 0)) || (NR_TASKLETS <= 3 ), "STACK_SIZE_TASKLET_3 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_4 % 8 == 0) && (STACK_SIZE_TASKLET_4 > 0)) || (NR_TASKLETS <= 4 ), "STACK_SIZE_TASKLET_4 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_5 % 8 == 0) && (STACK_SIZE_TASKLET_5 > 0)) || (NR_TASKLETS <= 5 ), "STACK_SIZE_TASKLET_5 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_6 % 8 == 0) && (STACK_SIZE_TASKLET_6 > 0)) || (NR_TASKLETS <= 6 ), "STACK_SIZE_TASKLET_6 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_7 % 8 == 0) && (STACK_SIZE_TASKLET_7 > 0)) || (NR_TASKLETS <= 7 ), "STACK_SIZE_TASKLET_7 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_8 % 8 == 0) && (STACK_SIZE_TASKLET_8 > 0)) || (NR_TASKLETS <= 8 ), "STACK_SIZE_TASKLET_8 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_9 % 8 == 0) && (STACK_SIZE_TASKLET_9 > 0)) || (NR_TASKLETS <= 9 ), "STACK_SIZE_TASKLET_9 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_10 % 8 == 0) && (STACK_SIZE_TASKLET_10 > 0)) || (NR_TASKLETS <= 10), "STACK_SIZE_TASKLET_10 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_11 % 8 == 0) && (STACK_SIZE_TASKLET_11 > 0)) || (NR_TASKLETS <= 11), "STACK_SIZE_TASKLET_11 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_12 % 8 == 0) && (STACK_SIZE_TASKLET_12 > 0)) || (NR_TASKLETS <= 12), "STACK_SIZE_TASKLET_12 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_13 % 8 == 0) && (STACK_SIZE_TASKLET_13 > 0)) || (NR_TASKLETS <= 13), "STACK_SIZE_TASKLET_13 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_14 % 8 == 0) && (STACK_SIZE_TASKLET_14 > 0)) || (NR_TASKLETS <= 14), "STACK_SIZE_TASKLET_14 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_15 % 8 == 0) && (STACK_SIZE_TASKLET_15 > 0)) || (NR_TASKLETS <= 15), "STACK_SIZE_TASKLET_15 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_16 % 8 == 0) && (STACK_SIZE_TASKLET_16 > 0)) || (NR_TASKLETS <= 16), "STACK_SIZE_TASKLET_16 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_17 % 8 == 0) && (STACK_SIZE_TASKLET_17 > 0)) || (NR_TASKLETS <= 17), "STACK_SIZE_TASKLET_17 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_18 % 8 == 0) && (STACK_SIZE_TASKLET_18 > 0)) || (NR_TASKLETS <= 18), "STACK_SIZE_TASKLET_18 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_19 % 8 == 0) && (STACK_SIZE_TASKLET_19 > 0)) || (NR_TASKLETS <= 19), "STACK_SIZE_TASKLET_19 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_20 % 8 == 0) && (STACK_SIZE_TASKLET_20 > 0)) || (NR_TASKLETS <= 20), "STACK_SIZE_TASKLET_20 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_21 % 8 == 0) && (STACK_SIZE_TASKLET_21 > 0)) || (NR_TASKLETS <= 21), "STACK_SIZE_TASKLET_21 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_22 % 8 == 0) && (STACK_SIZE_TASKLET_22 > 0)) || (NR_TASKLETS <= 22), "STACK_SIZE_TASKLET_22 should be a multiple of 8 and > 0") ASSERT(((STACK_SIZE_TASKLET_23 % 8 == 0) && (STACK_SIZE_TASKLET_23 > 0)) || (NR_TASKLETS <= 23), "STACK_SIZE_TASKLET_23 should be a multiple of 8 and > 0") ASSERT((NR_TASKLETS > 0 ) || (STACK_SIZE_TASKLET_0 == 0) , "STACK_SIZE_TASKLET_0 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 1 ) || (STACK_SIZE_TASKLET_1 == 0) , "STACK_SIZE_TASKLET_1 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 2 ) || (STACK_SIZE_TASKLET_2 == 0) , "STACK_SIZE_TASKLET_2 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 3 ) || (STACK_SIZE_TASKLET_3 == 0) , "STACK_SIZE_TASKLET_3 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 4 ) || (STACK_SIZE_TASKLET_4 == 0) , "STACK_SIZE_TASKLET_4 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 5 ) || (STACK_SIZE_TASKLET_5 == 0) , "STACK_SIZE_TASKLET_5 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 6 ) || (STACK_SIZE_TASKLET_6 == 0) , "STACK_SIZE_TASKLET_6 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 7 ) || (STACK_SIZE_TASKLET_7 == 0) , "STACK_SIZE_TASKLET_7 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 8 ) || (STACK_SIZE_TASKLET_8 == 0) , "STACK_SIZE_TASKLET_8 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 9 ) || (STACK_SIZE_TASKLET_9 == 0) , "STACK_SIZE_TASKLET_9 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 10) || (STACK_SIZE_TASKLET_10 == 0) , "STACK_SIZE_TASKLET_10 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 11) || (STACK_SIZE_TASKLET_11 == 0) , "STACK_SIZE_TASKLET_11 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 12) || (STACK_SIZE_TASKLET_12 == 0) , "STACK_SIZE_TASKLET_12 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 13) || (STACK_SIZE_TASKLET_13 == 0) , "STACK_SIZE_TASKLET_13 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 14) || (STACK_SIZE_TASKLET_14 == 0) , "STACK_SIZE_TASKLET_14 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 15) || (STACK_SIZE_TASKLET_15 == 0) , "STACK_SIZE_TASKLET_15 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 16) || (STACK_SIZE_TASKLET_16 == 0) , "STACK_SIZE_TASKLET_16 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 17) || (STACK_SIZE_TASKLET_17 == 0) , "STACK_SIZE_TASKLET_17 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 18) || (STACK_SIZE_TASKLET_18 == 0) , "STACK_SIZE_TASKLET_18 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 19) || (STACK_SIZE_TASKLET_19 == 0) , "STACK_SIZE_TASKLET_19 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 20) || (STACK_SIZE_TASKLET_20 == 0) , "STACK_SIZE_TASKLET_20 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 21) || (STACK_SIZE_TASKLET_21 == 0) , "STACK_SIZE_TASKLET_21 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 22) || (STACK_SIZE_TASKLET_22 == 0) , "STACK_SIZE_TASKLET_22 should be equal to 0 as the tasklet is not active") ASSERT((NR_TASKLETS > 23) || (STACK_SIZE_TASKLET_23 == 0) , "STACK_SIZE_TASKLET_23 should be equal to 0 as the tasklet is not active") . = ALIGN(8); __sys_stack_thread_0 = .; . += STACK_SIZE_TASKLET_0; __sys_stack_thread_1 = .; . += STACK_SIZE_TASKLET_1; __sys_stack_thread_2 = .; . += STACK_SIZE_TASKLET_2; __sys_stack_thread_3 = .; . += STACK_SIZE_TASKLET_3; __sys_stack_thread_4 = .; . += STACK_SIZE_TASKLET_4; __sys_stack_thread_5 = .; . += STACK_SIZE_TASKLET_5; __sys_stack_thread_6 = .; . += STACK_SIZE_TASKLET_6; __sys_stack_thread_7 = .; . += STACK_SIZE_TASKLET_7; __sys_stack_thread_8 = .; . += STACK_SIZE_TASKLET_8; __sys_stack_thread_9 = .; . += STACK_SIZE_TASKLET_9; __sys_stack_thread_10 = .; . += STACK_SIZE_TASKLET_10; __sys_stack_thread_11 = .; . += STACK_SIZE_TASKLET_11; __sys_stack_thread_12 = .; . += STACK_SIZE_TASKLET_12; __sys_stack_thread_13 = .; . += STACK_SIZE_TASKLET_13; __sys_stack_thread_14 = .; . += STACK_SIZE_TASKLET_14; __sys_stack_thread_15 = .; . += STACK_SIZE_TASKLET_15; __sys_stack_thread_16 = .; . += STACK_SIZE_TASKLET_16; __sys_stack_thread_17 = .; . += STACK_SIZE_TASKLET_17; __sys_stack_thread_18 = .; . += STACK_SIZE_TASKLET_18; __sys_stack_thread_19 = .; . += STACK_SIZE_TASKLET_19; __sys_stack_thread_20 = .; . += STACK_SIZE_TASKLET_20; __sys_stack_thread_21 = .; . += STACK_SIZE_TASKLET_21; __sys_stack_thread_22 = .; . += STACK_SIZE_TASKLET_22; __sys_stack_thread_23 = .; . += STACK_SIZE_TASKLET_23; . = ALIGN(8); } > wram .data.sw_cache (NOLOAD): { . = ALIGN(8); __sw_cache_buffer = .; . += 8 * NR_TASKLETS; } > wram .data.heap_pointer_reset (NOLOAD) : { /* Start of heap: must be aligned on DMA size. * Stored as a symbol "__reset_heap_pointer", so that * the bootstrap just moves the value into a register to * initialize heap pointer at each reboot. */ . = ALIGN(8); PROVIDE(__sys_heap_pointer_reset = .); } > wram .mram.noinit (NOLOAD) : { *(.mram.noinit .mram.noinit.*) KEEP(*(.mram.noinit.keep .mram.noinit.keep.*)) } > mram .mram : { *(.mram .mram.*) KEEP(*(.mram.keep .mram.keep.*)) . = ALIGN(8); __sys_used_mram_end = .; } > mram } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/internalStateReset.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The strict minimum to reset the internal state of the DPU (that can only be changed by a DPU program). */ #define __STR(x) __STR_AGAIN(x) #define __STR_AGAIN(x) #x void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " sub r0, " __STR(NR_ATOMIC_BITS) " - 1, id\n" "before_release:\n" // Resetting Atomic bits " release r0, 0, nz, after_release\n" "after_release:\n" " sub r0, r0, " __STR(NR_THREADS) ", pl, before_release\n" // Resetting Zero and Carry flags + Preparing configuration for perfcounter register " add r0, zero, 7\n" // Resetting Performance Counter " time_cfg zero, r0\n" // Resetting Pc " stop true, 0\n"); /* clang-format on */ } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/linkerScript.lds ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Simple linker script for embedded programs. */ ENTRY(__bootstrap) MEMORY { iram (rx) : ORIGIN = 0x80000000, LENGTH = 32K } SECTIONS { /* * Merge every text section into .text. */ .text : { *(.text) } > iram } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/restoreRegisters.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * The "restore registers" program, is used by debugging processes to restore every registers of every runtime. * The program should be booted once on runtime 0. */ #include "restore_carry_and_zero_flag.h" void __attribute__((naked, used, section(".text.__bootstrap"))) __bootstrap() { /* clang-format off */ __asm__ volatile( " jeq id, " __STR(NR_THREADS) " - 1, .+2\n" " boot id, 1\n" " ld d2, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 1)\n" " ld d4, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 2)\n" " ld d6, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 3)\n" " ld d8, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 4)\n" " ld d10, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 5)\n" " ld d12, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 6)\n" " ld d14, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 7)\n" " ld d16, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 8)\n" " ld d18, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 9)\n" " ld d20, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 10)\n" " ld d22, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 11)\n" " jnz id, atomic_done\n" " move r0, " __STR(NR_ATOMIC_BITS) " - 1\n" "atomic_loop:\n" " lbu r1, r0, 0\n" " jz r1, atomic_release\n" " acquire r0, 0, true, atomic_next\n" "atomic_release:\n" " release r0, 0, nz, atomic_next\n" "atomic_next:\n" " add r0, r0, -1, pl, atomic_loop\n" "atomic_done:\n" RESTORE_CARRY_AND_ZERO_FLAG ); /* clang-format on */ } ================================================ FILE: golang_vm/uPIMulator/sdk/misc/restore_carry_and_zero_flag.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "macro_utils.h" /* clang-format off */ #define __RESTORE_CARRY_AND_ZERO_FLAG(x) \ "add r0, zero, 0x00000001; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 0, C = 0 */ \ "add r0, mneg, 0x80000001; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 0, C = 1 */ \ "add r0, zero, 0x00000000; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" /* ... restore Z = 1, C = 0 */ \ "add r0, mneg, 0x80000000; ld d0, id8, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 0); stop true, 0\n" // ... restore Z = 1, C = 1 */ #define RESTORE_CARRY_AND_ZERO_FLAG \ " lw r0, id4, " __STR(NR_ATOMIC_BITS) " + (" __STR(NR_THREADS) " * 8 * 12)\n" \ " add r1, r0, r0\n" \ " add r0, r0, r1\n" /* r0 = 3 * r0 (each line of ending_routines is 3 instructions) */ \ " or r1, id8, 0 \n" \ " add r1, id4, r1\n" /* r1 = 12 * id (there are 12 instructions per runtime in ending_routines) */ \ " add r0, r0, r1\n" /* r0 = r0 + r1 (compute the offset (in number of instructions) to jump to) */ \ " call zero, r0, ending_routines\n" \ "ending_routines:\n" \ __FOR_EACH_THREAD(__RESTORE_CARRY_AND_ZERO_FLAG) /* clang-format on */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(stdlib ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/abort.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void abort() { halt(); } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/assert.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ASSERT_H_ #define _DPUSYSCORE_ASSERT_H_ /** * @file assert.h * @brief Provides a way to verify assumptions with assert. */ #define static_assert _Static_assert #ifdef NDEBUG /** * @def assert * @hideinitializer * @brief When NDEBUG is defined, assert is not available and calling it will do nothing. */ #define assert(ignore) ((void)0) #else #include #include /** * @def assert * @hideinitializer * @brief Verify the assumption of the specified expression, resulting in a fault if it fails. * * @param expression the assumption to verify * @throws FAULT_ASSERT_FAILED when the assertion failed * @todo add a diagnostic message to the log, if it exists, when the assertion fails */ #define assert(expression) \ do { \ if (!(expression)) { \ __asm__ volatile("fault " __STR(__FAULT_ASSERT_FAILED__)); \ } \ } while (0) #endif /* NDEBUG */ #endif /* _DPUSYSCORE_ASSERT_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/atoi.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include int atoi(const char *nptr) { int result = 0; bool is_positive = true; if (nptr == NULL) { return result; } while (isspace(*nptr)) { nptr++; } if (*nptr == '-') { is_positive = false; nptr++; } else if (*nptr == '+') { nptr++; } for (;; nptr++) { unsigned int digit = *nptr - '0'; if (digit > 9) { break; } result = (10 * result) + digit; } return is_positive ? result : -result; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/atol.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include long atol(const char *nptr) { long result = 0; bool is_positive = true; if (nptr == NULL) { return result; } while (isspace(*nptr)) { nptr++; } if (*nptr == '-') { is_positive = false; nptr++; } else if (*nptr == '+') { nptr++; } for (;; nptr++) { unsigned int digit = *nptr - '0'; if (digit > 9) { break; } result = (10 * result) + digit; } return is_positive ? result : -result; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/ctype.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_CTYPE_H_ #define _DPUSYSCORE_CTYPE_H_ /** * @file ctype.h * @brief Provides useful functions for testing and mapping characters. */ /** * @brief Checks whether the specified character is a digit. * @param c an unsigned char or EOF * @return Whether the character is a digit (using 0 as false and anything else as true). */ static inline int isdigit(int c) { return (c >= '0') && (c <= '9'); } /** * @brief Checks whether the specified character is a lowercase letter. * @param c an unsigned char or EOF * @return Whether the character is a digit (using 0 as false and anything else as true). */ static inline int islower(c) { return (c >= 'a') && (c <= 'z'); } /** * @brief Checks whether the specified character is an uppercase letter. * @param c an unsigned char or EOF * @return Whether the character is an uppercase letter (using 0 as false and anything else as true). */ static inline int isupper(c) { return (c >= 'A') && (c <= 'Z'); } /** * @brief Checks whether the specified character is a letter. * @param c an unsigned char or EOF * @return Whether the character is a letter (using 0 as false and anything else as true). */ static inline int isalpha(int c) { return islower(c) || isupper(c); } /** * @brief Checks whether the specified character is a letter or a digit. * @param c an unsigned char or EOF * @return Whether the character is a letter or a digit (using 0 as false and anything else as true). */ static inline int isalnum(int c) { return isalpha(c) || isdigit(c); } /** * @brief Checks whether the specified character is a control character. * @param c an unsigned char or EOF * @return Whether the character is a control character (using 0 as false and anything else as true). */ static inline int iscntrl(int c) { return (c <= 0x1f) || (c == 0x7f); } /** * @brief Checks whether the specified character is printable. * @param c an unsigned char or EOF * @return Whether the character is printable (using 0 as false and anything else as true). */ static inline int isprint(int c) { return !iscntrl(c); } /** * @brief Checks whether the specified character has graphical representation using locale. * @param c an unsigned char or EOF * @return Whether the character has graphical representation using locale (using 0 as false and anything else as true). */ static inline int isgraph(int c) { return isprint(c) && (c != ' '); } /** * @brief Checks whether the specified character is a punctuation character. * @param c an unsigned char or EOF * @return Whether the character is a punctuation character (using 0 as false and anything else as true). */ static inline int ispunct(int c) { return (c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~'); } /** * @brief Checks whether the specified character is a white-space. * @param c an unsigned char or EOF * @return Whether the character is a white-space (using 0 as false and anything else as true). */ static inline int isspace(int c) { return (c >= 0x9 && c <= 0xd) || (c == ' '); } /** * @brief Checks whether the specified character is a hexadecimal digit. * @param c an unsigned char or EOF * @return Whether the character is a hexadecimal digit (using 0 as false and anything else as true). */ static inline int isxdigit(int c) { return isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } /** * @brief Checks whether the specified character is a blank character. * @param c an unsigned char or EOF * @return Whether the character is a blank character (using 0 as false and anything else as true). */ static inline int isblank(int c) { return c == ' ' || c == '\t'; } /** * @brief Converts the specified character to a lowercase letter if it is a letter; * @param c an unsigned char or EOF * @return The lowercase letter corresponding to the character, if it is a letter. The initial character otherwise. */ static inline int tolower(int c) { return isupper(c) ? (c + 0x20) : c; } /** * @brief Converts the specified character to a uppercase letter if it is a letter; * @param c an unsigned char or EOF * @return The uppercase letter corresponding to the character, if it is a letter. The initial character otherwise. */ static inline int toupper(int c) { return islower(c) ? (c - 0x20) : c; } #endif /* _DPUSYSCORE_CTYPE_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/errno.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ int __errno[NR_THREADS]; ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/errno.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ERRNO_H_ #define _DPUSYSCORE_ERRNO_H_ #include /** * @file errno.h * @brief Defines the system error numbers. */ // errno is an array indexed on the tasklet id rather than // a single integer. extern int __errno[]; // Mimic errno variable as an index to __errno. // Defined in such a way that users can't override errno. #define errno (*(__errno + me())) /** * @def E2BIG * @brief Argument list too long. */ #define E2BIG 1 /** * @def EACCES * @brief Permission denied. */ #define EACCES 2 /** * @def EADDRINUSE * @brief Address in use. */ #define EADDRINUSE 3 /** * @def EADDRNOTAVAIL * @brief Address not available. */ #define EADDRNOTAVAIL 4 /** * @def EAFNOSUPPORT * @brief Address family not supported. */ #define EAFNOSUPPORT 5 /** * @def EAGAIN * @brief Resource unavailable, try again. */ #define EAGAIN 6 /** * @def EALREADY * @brief Connection already in progress. */ #define EALREADY 7 /** * @def EBADF * @brief Bad file descriptor. */ #define EBADF 8 /** * @def EBADMSG * @brief Bad message. */ #define EBADMSG 9 /** * @def EBUSY * @brief Device or resource busy. */ #define EBUSY 10 /** * @def ECANCELED * @brief Operation canceled. */ #define ECANCELED 11 /** * @def ECHILD * @brief No child processes. */ #define ECHILD 12 /** * @def ECONNABORTED * @brief Connection aborted. */ #define ECONNABORTED 13 /** * @def ECONNREFUSED * @brief Connection refused. */ #define ECONNREFUSED 14 /** * @def ECONNRESET * @brief Connection reset. */ #define ECONNRESET 15 /** * @def EDEADLK * @brief Resource deadlock would occur. */ #define EDEADLK 16 /** * @def EDESTADDRREQ * @brief Destination address required. */ #define EDESTADDRREQ 17 /** * @def EDOM * @brief Mathematics argument out of domain of function. */ #define EDOM 18 /** * @def EDQUOT * @brief Reserved. */ #define EDQUOT 19 /** * @def EEXIST * @brief File exists. */ #define EEXIST 20 /** * @def EFAULT * @brief Bad address. */ #define EFAULT 21 /** * @def EFBIG * @brief File too large. */ #define EFBIG 22 /** * @def EHOSTUNREACH * @brief Host is unreachable. */ #define EHOSTUNREACH 23 /** * @def EIDRM * @brief Identifier removed. */ #define EIDRM 24 /** * @def EILSEQ * @brief Illegal byte sequence. */ #define EILSEQ 25 /** * @def EINPROGRESS * @brief Operation in progress. */ #define EINPROGRESS 26 /** * @def EINTR * @brief Interrupted function. */ #define EINTR 27 /** * @def EINVAL * @brief Invalid argument. */ #define EINVAL 28 /** * @def EIO * @brief I/O error. */ #define EIO 29 /** * @def EISCONN * @brief Socket is connected. */ #define EISCONN 30 /** * @def EISDIR * @brief Is a directory. */ #define EISDIR 31 /** * @def ELOOP * @brief Too many levels of symbolic links. */ #define ELOOP 32 /** * @def EMFILE * @brief File descriptor value too large. */ #define EMFILE 33 /** * @def EMLINK * @brief Too many links. */ #define EMLINK 34 /** * @def EMSGSIZE * @brief Message too large. */ #define EMSGSIZE 35 /** * @def EMULTIHOP * @brief Reserved. */ #define EMULTIHOP 36 /** * @def ENAMETOOLONG * @brief Filename too long. */ #define ENAMETOOLONG 37 /** * @def ENETDOWN * @brief Network is down. */ #define ENETDOWN 38 /** * @def ENETRESET * @brief Connection aborted by network. */ #define ENETRESET 39 /** * @def ENETUNREACH * @brief Network unreachable. */ #define ENETUNREACH 40 /** * @def ENFILE * @brief Too many files open in system. */ #define ENFILE 41 /** * @def ENOBUFS * @brief No buffer space available. */ #define ENOBUFS 42 /** * @def ENODATA * @brief No message is available on the STREAM head read queue. */ #define ENODATA 43 /** * @def ENODEV * @brief No such device. */ #define ENODEV 44 /** * @def ENOENT * @brief No such file or directory. */ #define ENOENT 45 /** * @def ENOEXEC * @brief Executable file format error. */ #define ENOEXEC 46 /** * @def ENOLCK * @brief No locks available. */ #define ENOLCK 47 /** * @def ENOLINK * @brief Reserved. */ #define ENOLINK 48 /** * @def ENOMEM * @brief Not enough space. */ #define ENOMEM 49 /** * @def ENOMSG * @brief No message of the desired type. */ #define ENOMSG 50 /** * @def ENOPROTOOPT * @brief Protocol not available. */ #define ENOPROTOOPT 51 /** * @def ENOSPC * @brief No space left on device. */ #define ENOSPC 52 /** * @def ENOSR * @brief No STREAM resources. */ #define ENOSR 53 /** * @def ENOSTR * @brief Not a STREAM. */ #define ENOSTR 54 /** * @def ENOSYS * @brief Function not supported. */ #define ENOSYS 55 /** * @def ENOTCONN * @brief The socket is not connected. */ #define ENOTCONN 56 /** * @def ENOTDIR * @brief Not a directory or a symbolic link to a directory. */ #define ENOTDIR 57 /** * @def ENOTEMPTY * @brief Directory not empty. */ #define ENOTEMPTY 58 /** * @def ENOTRECOVERABLE * @brief State not recoverable. */ #define ENOTRECOVERABLE 59 /** * @def ENOTSOCK * @brief Not a socket. */ #define ENOTSOCK 60 /** * @def ENOTSUP * @brief Not supported. */ #define ENOTSUP 61 /** * @def ENOTTY * @brief Inappropriate I/O control operation. */ #define ENOTTY 62 /** * @def ENXIO * @brief No such device or address. */ #define ENXIO 63 /** * @def EOPNOTSUPP * @brief Operation not supported on socket. */ #define EOPNOTSUPP ENOTSUP /** * @def EOVERFLOW * @brief Value too large to be stored in data type. */ #define EOVERFLOW 65 /** * @def EOWNERDEAD * @brief Previous owner died. */ #define EOWNERDEAD 66 /** * @def EPERM * @brief Operation not permitted. */ #define EPERM 67 /** * @def EPIPE * @brief Broken pipe. */ #define EPIPE 68 /** * @def EPROTO * @brief Protocol error. */ #define EPROTO 69 /** * @def EPROTONOSUPPORT * @brief Protocol not supported. */ #define EPROTONOSUPPORT 70 /** * @def EPROTOTYPE * @brief Protocol wrong type for socket. */ #define EPROTOTYPE 71 /** * @def ERANGE * @brief Result too large. */ #define ERANGE 72 /** * @def EROFS * @brief Read-only file system. */ #define EROFS 73 /** * @def ESPIPE * @brief Invalid seek. */ #define ESPIPE 74 /** * @def ESRCH * @brief No such process. */ #define ESRCH 75 /** * @def ESTALE * @brief Reserved. */ #define ESTALE 76 /** * @def ETIME * @brief Stream ioctl() timeout. */ #define ETIME 77 /** * @def ETIMEDOUT * @brief Connection timed out. */ #define ETIMEDOUT 78 /** * @def ETXTBSY * @brief Text file busy. */ #define ETXTBSY 79 /** * @def EWOULDBLOCK * @brief Operation would block. */ #define EWOULDBLOCK ENOTSUP /** * @def EXDEV * @brief Cross-device link. */ #define EXDEV 81 #endif /* _DPUSYSCORE_ERRNO_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/exit.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "defs.h" #include "stdlib.h" #define unreachable() __builtin_unreachable() void exit(int __attribute__((unused)) status) { __asm__ volatile("stop true, __sys_end"); unreachable(); } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/inttypes.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_INTTYPES_H_ #define _DPUSYSCORE_INTTYPES_H_ /** * @file inttypes.h * @brief Extends stdint.h. */ #include typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; static inline intmax_t imaxabs(intmax_t x) { return (x < 0) ? -x : x; } static inline imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) { imaxdiv_t result = { numer / denom, numer % denom }; return result; } /* Macros for printing format specifiers. */ /* Decimal notation. */ #define PRId8 "d" #define PRId16 "d" #define PRId32 "d" #define PRId64 "ld" #define PRIdLEAST8 "d" #define PRIdLEAST16 "d" #define PRIdLEAST32 "d" #define PRIdLEAST64 "ld" #define PRIdFAST8 "d" #define PRIdFAST16 "d" #define PRIdFAST32 "d" #define PRIdFAST64 "ld" #define PRIi8 "i" #define PRIi16 "i" #define PRIi32 "i" #define PRIi64 "li" #define PRIiLEAST8 "i" #define PRIiLEAST16 "i" #define PRIiLEAST32 "i" #define PRIiLEAST64 "li" #define PRIiFAST8 "i" #define PRIiFAST16 "i" #define PRIiFAST32 "i" #define PRIiFAST64 "li" /* Octal notation. */ #define PRIo8 "o" #define PRIo16 "o" #define PRIo32 "o" #define PRIo64 "lo" #define PRIoLEAST8 "o" #define PRIoLEAST16 "o" #define PRIoLEAST32 "o" #define PRIoLEAST64 "lo" #define PRIoFAST8 "o" #define PRIoFAST16 "o" #define PRIoFAST32 "o" #define PRIoFAST64 "lo" /* Unsigned integers. */ #define PRIu8 "u" #define PRIu16 "u" #define PRIu32 "u" #define PRIu64 "lu" #define PRIuLEAST8 "u" #define PRIuLEAST16 "u" #define PRIuLEAST32 "u" #define PRIuLEAST64 "lu" #define PRIuFAST8 "u" #define PRIuFAST16 "u" #define PRIuFAST32 "u" #define PRIuFAST64 "lu" /* lowercase hexadecimal notation. */ #define PRIx8 "x" #define PRIx16 "x" #define PRIx32 "x" #define PRIx64 "lx" #define PRIxLEAST8 "x" #define PRIxLEAST16 "x" #define PRIxLEAST32 "x" #define PRIxLEAST64 "lx" #define PRIxFAST8 "x" #define PRIxFAST16 "x" #define PRIxFAST32 "x" #define PRIxFAST64 "lx" /* UPPERCASE hexadecimal notation. */ #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "X" #define PRIX64 "lX" #define PRIXLEAST8 "X" #define PRIXLEAST16 "X" #define PRIXLEAST32 "X" #define PRIXLEAST64 "lX" #define PRIXFAST8 "X" #define PRIXFAST16 "X" #define PRIXFAST32 "X" #define PRIXFAST64 "lX" /* Macros for printing `intmax_t' and `uintmax_t'. */ #define PRIdMAX "ld" #define PRIiMAX "li" #define PRIoMAX "lo" #define PRIuMAX "lu" #define PRIxMAX "lx" #define PRIXMAX "lX" /* Macros for printing `intptr_t' and `uintptr_t'. */ #define PRIdPTR "d" #define PRIiPTR "i" #define PRIoPTR "o" #define PRIuPTR "u" #define PRIxPTR "x" #define PRIXPTR "X" #endif /* _DPUSYSCORE_INTTYPES_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/iso646.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_ISO646_H_ #define _DPUSYSCORE_ISO646_H_ /** * @file iso646.h * @brief Alternative spellings for operators not supported by the ISO646 standard character set. */ /** * @def and * @brief Logical AND. */ #define and && /** * @def and_eq * @brief Bitwise AND accumulation. */ #define and_eq &= /** * @def bitand * @brief Bitwise AND. */ #define bitand & /** * @def bitor * @brief Bitwise OR. */ #define bitor | /** * @def compl * @brief Bitwise NOT. */ #define compl ~ /** * @def not * @brief Logical NOT. */ #define not ! /** * @def not_eq * @brief Difference. */ #define not_eq != /** * @def or * @brief Logical OR. */ #define or || /** * @def or_eq * @brief Bitwise OR accumulation. */ #define or_eq |= /** * @def xor * @brief Bitwise XOR. */ #define xor ^ /** * @def xor_eq * @brief Bitwise XOR accumulation. */ #define xor_eq ^= #endif /* _DPUSYSCORE_ISO646_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/limits.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_LIMITS_H_ #define _DPUSYSCORE_LIMITS_H_ #define SCHAR_MAX (0x0000007f) #define SHRT_MAX (0x00007fff) #define INT_MAX (0x7fffffff) #define LONG_MAX (0x7fffffffffffffffl) #define LLONG_MAX (0x7fffffffffffffffl) #define SCHAR_MIN (-SCHAR_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1) #define INT_MIN (-INT_MAX - 1) #define LONG_MIN (-LONG_MAX - 1) #define LLONG_MIN (-LLONG_MAX - 1) #define UCHAR_MAX (SCHAR_MAX * 2 + 1) #define USHRT_MAX (SHRT_MAX * 2 + 1) #define UINT_MAX (INT_MAX * 2U + 1U) #define ULONG_MAX (LONG_MAX * 2UL + 1UL) #define ULLONG_MAX (LLONG_MAX * 2UL + 1UL) #ifdef __CHAR_UNSIGNED__ /* -funsigned-char */ #define CHAR_MIN 0 #define CHAR_MAX UCHAR_MAX #else #define CHAR_MIN SCHAR_MIN #define CHAR_MAX SCHAR_MAX #endif /* The maximum number of bytes in a multi-byte character. */ #define MB_LEN_MAX 16 /* Limits of integral types */ /** * @def CHAR_BIT * @hideinitializer * @brief The number of bits in a char type. */ #define CHAR_BIT (8) /** * @def WORD_BIT * @hideinitializer * @brief The number of bits in a word type. */ #define WORD_BIT (32) /** * @def LONG_BIT * @hideinitializer * @brief The number of bits in a pseudo-long type. */ #define LONG_BIT (32) /* Minimum of signed integral types */ /** * @def INT8_MIN * @hideinitializer * @brief The minimum value for a value of type int8_t. */ #define INT8_MIN (-0x7f - 1) /** * @def INT16_MIN * @hideinitializer * @brief The minimum value for a value of type int16_t. */ #define INT16_MIN (-0x7fff - 1) /** * @def INT32_MIN * @hideinitializer * @brief The minimum value for a value of type int32_t. */ #define INT32_MIN (-0x7fffffff - 1) /** * @def INT64_MIN * @hideinitializer * @brief The minimum value for a value of type int64_t. */ #define INT64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of signed integral types */ /** * @def INT8_MAX * @hideinitializer * @brief The maximum value for a value of type int8_t. */ #define INT8_MAX (0x7f) /** * @def INT16_MAX * @hideinitializer * @brief The maximum value for a value of type int16_t. */ #define INT16_MAX (0x7fff) /** * @def INT32_MAX * @hideinitializer * @brief The maximum value for a value of type int32_t. */ #define INT32_MAX (0x7fffffff) /** * @def INT64_MAX * @hideinitializer * @brief The maximum value for a value of type int64_t. */ #define INT64_MAX (0x7fffffffffffffffL) /* Maximum of unsigned integral types */ /** * @def UINT8_MAX * @hideinitializer * @brief The maximum value for a value of type uint8_t. */ #define UINT8_MAX (0xff) /** * @def UINT16_MAX * @hideinitializer * @brief The maximum value for a value of type uint16_t. */ #define UINT16_MAX (0xffff) /** * @def UINT32_MAX * @hideinitializer * @brief The maximum value for a value of type uint32_t. */ #define UINT32_MAX (0xffffffff) /** * @def UINT64_MAX * @hideinitializer * @brief The maximum value for a value of type uint64_t. */ #define UINT64_MAX (0xffffffffffffffffUL) /* Minimum of signed integral types having a minimum size */ /** * @def INT_LEAST8_MIN * @hideinitializer * @brief The minimum value for a value of type int_least8_t. */ #define INT_LEAST8_MIN (-0x7f - 1) /** * @def INT_LEAST16_MIN * @hideinitializer * @brief The minimum value for a value of type int_least16_t. */ #define INT_LEAST16_MIN (-0x7fff - 1) /** * @def INT_LEAST32_MIN * @hideinitializer * @brief The minimum value for a value of type int_least32_t. */ #define INT_LEAST32_MIN (-0x7fffffff - 1) /** * @def INT_LEAST64_MIN * @hideinitializer * @brief The minimum value for a value of type int_least64_t. */ #define INT_LEAST64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of signed integral types having a minimum size */ /** * @def INT_LEAST8_MAX * @hideinitializer * @brief The maximum value for a value of type int_least8_t. */ #define INT_LEAST8_MAX (0x7f) /** * @def INT_LEAST16_MAX * @hideinitializer * @brief The maximum value for a value of type int_least16_t. */ #define INT_LEAST16_MAX (0x7fff) /** * @def INT_LEAST32_MAX * @hideinitializer * @brief The maximum value for a value of type int_least32_t. */ #define INT_LEAST32_MAX (0x7fffffff) /** * @def INT_LEAST64_MAX * @hideinitializer * @brief The maximum value for a value of type int_least64_t. */ #define INT_LEAST64_MAX (0x7fffffffffffffffL) /* Maximum of unsigned integral types having a minimum size */ /** * @def UINT_LEAST8_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least8_t. */ #define UINT_LEAST8_MAX (0xff) /** * @def UINT_LEAST16_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least16_t. */ #define UINT_LEAST16_MAX (0xffff) /** * @def UINT_LEAST32_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least32_t. */ #define UINT_LEAST32_MAX (0xffffffff) /** * @def UINT_LEAST64_MAX * @hideinitializer * @brief The maximum value for a value of type uint_least64_t. */ #define UINT_LEAST64_MAX (0xffffffffffffffffUL) /* Minimum of fast signed integral types having a minimum size */ /** * @def INT_FAST8_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast8_t. */ #define INT_FAST8_MIN (-0x7f - 1) /** * @def INT_FAST16_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast16_t. */ #define INT_FAST16_MIN (-0x7fffffff - 1) /** * @def INT_FAST32_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast32_t. */ #define INT_FAST32_MIN (-0x7fffffff - 1) /** * @def INT_FAST64_MIN * @hideinitializer * @brief The minimum value for a value of type int_fast64_t. */ #define INT_FAST64_MIN (-0x7fffffffffffffffL - 1L) /* Maximum of fast signed integral types having a minimum size */ /** * @def INT_FAST8_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast8_t. */ #define INT_FAST8_MAX (0x7f) /** * @def INT_FAST16_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast16_t. */ #define INT_FAST16_MAX (0x7fffffff) /** * @def INT_FAST32_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast32_t. */ #define INT_FAST32_MAX (0x7fffffff) /** * @def INT_FAST64_MAX * @hideinitializer * @brief The maximum value for a value of type int_fast64_t. */ #define INT_FAST64_MAX (0x7fffffffffffffffL) /* Maximum of fast unsigned integral types having a minimum size */ /** * @def UINT_FAST8_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast8_t. */ #define UINT_FAST8_MAX (0xff) /** * @def UINT_FAST16_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast16_t. */ #define UINT_FAST16_MAX (0xffffffffU) /** * @def UINT_FAST32_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast32_t. */ #define UINT_FAST32_MAX (0xffffffffU) /** * @def UINT_FAST64_MAX * @hideinitializer * @brief The maximum value for a value of type uint_fast64_t. */ #define UINT_FAST64_MAX (0xffffffffffffffffUL) /* Limits for integral types holding void* pointers */ /** * @def INTPTR_MIN * @hideinitializer * @brief The minimum value for a value of type intptr_t. */ #define INTPTR_MIN (-0x7fffffff - 1) /** * @def INTPTR_MAX * @hideinitializer * @brief The maximum value for a value of type intptr_t. */ #define INTPTR_MAX (0x7fffffff) /** * @def UINTPTR_MAX * @hideinitializer * @brief The maximum value for a value of type uintptr_t. */ #define UINTPTR_MAX (0xffffffffU) /* Limits of greatest-width integer types */ /** * @def INTMAX_MIN * @hideinitializer * @brief The minimum value for a value of type intmax_t. */ #define INTMAX_MIN (-0x7fffffffffffffffLL - 1) /** * @def INTMAX_MAX * @hideinitializer * @brief The maximum value for a value of type intmax_t. */ #define INTMAX_MAX (0x7fffffffffffffffLL) /** * @def UINTMAX_MAX * @hideinitializer * @brief The maximum value for a value of type uintmax_t. */ #define UINTMAX_MAX (0xffffffffffffffffULL) /* Limits of others integer types */ /** * @def PTRDIFF_MIN * @hideinitializer * @brief The minimum value for a value of type ptrdiff_t. * @see ptrdiff_t */ #define PTRDIFF_MIN (-0x7fffffff - 1) /** * @def PTRDIFF_MAX * @hideinitializer * @brief The maximum value for a value of type ptrdiff_t. * @see ptrdiff_t */ #define PTRDIFF_MAX (0x7fffffff) /** * @def SIZE_MAX * @hideinitializer * @brief The maximum value for a value of type size_t. * @see size_t */ #define SIZE_MAX (0xffffffffU) /** * @def WCHAR_MIN * @hideinitializer * @brief The minimum value for a value of type wchar_t. * @see wchar_t */ #define WCHAR_MIN (-0x7fffffff - 1) /** * @def WCHAR_MAX * @hideinitializer * @brief The maximum value for a value of type wchar_t. * @see wchar_t */ #define WCHAR_MAX (0x7fffffff) /** * @def WINT_MIN * @hideinitializer * @brief The minimum value for a value of type wint_t. */ #define WINT_MIN (0u) /** * @def WINT_MAX * @hideinitializer * @brief The maximum value for a value of type wint_t. */ #define WINT_MAX (0xffffffffu) /* Macros for integer constant expressions */ /* Signed */ /** * @def INT8_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least8_t */ #define INT8_C(value) value /** * @def INT16_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least16_t */ #define INT16_C(value) value /** * @def INT32_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least32_t */ #define INT32_C(value) value /** * @def INT64_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type int_least64_t */ #define INT64_C(value) value##LL /* Unsigned */ /** * @def UINT8_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least8_t */ #define UINT8_C(value) value##U /** * @def UINT16_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least16_t */ #define UINT16_C(value) value##U /** * @def UINT32_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least32_t */ #define UINT32_C(value) value##U /** * @def UINT64_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uint_least64_t */ #define UINT64_C(value) value##ULL /* Maximum types */ /** * @def INTMAX_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type intmax_t */ #define INTMAX_C(value) value##LL /** * @def UINTMAX_C * @hideinitializer * @brief Expands the value to an expression corresponding to the type uintmax_t */ #define UINTMAX_C(value) value##ULL #endif /* _DPUSYSCORE_LIMITS_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void * memchr(const void *area, int character, size_t size) { const char *ptr = (const char *)area; for (size_t each_byte = 0; each_byte < size; ++each_byte) { if (ptr[each_byte] == character) { return (void *)(ptr + each_byte); } } return NULL; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memcmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int memcmp(const void *area1, const void *area2, size_t size) { const unsigned char *ptr1 = (const unsigned char *)area1; const unsigned char *ptr2 = (const unsigned char *)area2; for (size_t each_byte = 0; each_byte < size; ++each_byte) { int diff = ptr1[each_byte] - ptr2[each_byte]; if (diff != 0) { return diff; } } return 0; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include __attribute__((used)) void * __memcpy_wram_4align(void *dest, const void *src, size_t len) { uint32_t *dw = (uint32_t *)dest; uint32_t *sw = (uint32_t *)src; for (uint32_t i = 0; i < (len / sizeof(uint32_t)); ++i) { dw[i] = sw[i]; } return dest; } void * memcpy(void *dest, const void *src, size_t len) { uint8_t *d = (uint8_t *)dest; const uint8_t *s = (const uint8_t *)src; uint32_t *dw; const uint32_t *sw; uint8_t *head; uint8_t *const tail = (uint8_t *)dest + len; /* Set 'body' to the last word boundary */ uint32_t *const body = (uint32_t *)((uintptr_t)tail & ~3); if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { /* Misaligned. no body, no tail. */ head = tail; } else { /* Aligned */ if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) /* len is shorter than the first word boundary */ head = tail; else /* Set 'head' to the first word boundary */ head = (uint8_t *)(((uintptr_t)d + 3) & ~3); } /* Copy head */ uint32_t head_len = head - d; if (head_len != 0) { for (uint32_t i = 0; i < head_len; ++i) d[i] = s[i]; } /* Copy body */ dw = (uint32_t *)(d + head_len); sw = (uint32_t *)(s + head_len); uint32_t body_len = (body < dw) ? 0 : body - dw; if (body_len != 0) { __memcpy_wram_4align(dw, sw, body_len * sizeof(uint32_t)); } /* Copy tail */ d = (uint8_t *)(dw + body_len); s = (const uint8_t *)(sw + body_len); uint32_t tail_len = tail - d; if (tail_len != 0) { for (uint32_t i = 0; i < tail_len; ++i) d[i] = s[i]; } return dest; } __attribute__((used)) __mram_ptr void * __memcpy_mw(__mram_ptr void *dest, const void *src, size_t len) { uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *destCache = (void *)destCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; uint32_t idx = 0; if (destOff != 0) { size_t part = MIN(remaining, MRAM_CACHE_SIZE - destOff); mram_read(dest, destCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, src, part); mram_write(destCache, dest, MRAM_CACHE_SIZE); remaining -= part; idx += part; } if (srcOff == destOff) { while (remaining >= MRAM_CACHE_SIZE) { mram_write(src + idx, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } else { while (remaining >= MRAM_CACHE_SIZE) { memcpy(destCache, src + idx, MRAM_CACHE_SIZE); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } if (remaining != 0) { mram_read(dest + idx, destCache, MRAM_CACHE_SIZE); memcpy(destCache, src + idx, remaining); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); } return dest; } __attribute__((used)) void * __memcpy_wm(void *dest, const __mram_ptr void *src, size_t len) { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; uint32_t idx = 0; size_t part = MIN(remaining, MRAM_CACHE_SIZE - srcOff); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(dest, srcCache + srcOff, part); remaining -= part; idx += part; if (srcOff == destOff) { while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } else { while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(dest + idx, srcCache, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } } if (remaining != 0) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(dest + idx, srcCache, remaining); } return dest; } __attribute__((used)) __mram_ptr void * __memcpy_mm(__mram_ptr void *dest, const __mram_ptr void *src, size_t len) { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; void *destCache = (void *)destCache64; uint32_t srcOff = ((uintptr_t)src) & DMA_OFF_MASK; uint32_t destOff = ((uintptr_t)dest) & DMA_OFF_MASK; size_t remaining = len; if (srcOff == destOff) { uint32_t idx = 0; if (destOff != 0) { size_t part = MIN(remaining, MRAM_CACHE_SIZE - srcOff); mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, srcCache + srcOff, part); mram_write(destCache, dest, MRAM_CACHE_SIZE); remaining -= part; idx += part; } while (remaining >= MRAM_CACHE_SIZE) { mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); mram_write(srcCache, dest + idx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; idx += MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dest + idx, destCache, MRAM_CACHE_SIZE); mram_read(src + idx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache, srcCache, remaining); mram_write(destCache, dest + idx, MRAM_CACHE_SIZE); } } else { uint32_t srcIdx = 0; uint32_t destIdx = 0; size_t initLen = MIN(remaining, MRAM_CACHE_SIZE - MIN(destOff, srcOff)); if (initLen == remaining) { mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + destOff, srcCache + srcOff, remaining); mram_write(destCache, dest, MRAM_CACHE_SIZE); return dest; } mram_read(src, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; if (destOff != 0) { mram_read(dest, destCache, DMA_ALIGNED(destOff)); if (destOff > srcOff) { size_t part = MRAM_CACHE_SIZE - destOff; memcpy(destCache + destOff, srcCache + srcOff, part); srcOff += part; } else { size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache + destOff, srcCache + srcOff, part); mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; size_t part2 = srcOff - destOff; memcpy(destCache + destOff + part, srcCache, part2); srcOff = part2; } mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); destIdx += MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE - destOff; } while (remaining >= MRAM_CACHE_SIZE) { size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache, srcCache + srcOff, part); mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx += MRAM_CACHE_SIZE; size_t part2 = srcOff; memcpy(destCache + part, srcCache, part2); mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; destIdx += MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dest + destIdx, destCache, MRAM_CACHE_SIZE); size_t part = MRAM_CACHE_SIZE - srcOff; memcpy(destCache, srcCache + srcOff, part); if (remaining > part) { size_t part2 = remaining - part; mram_read(src + srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + part, srcCache, part2); } mram_write(destCache, dest + destIdx, MRAM_CACHE_SIZE); } } return dest; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memmove.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include void * memmove(void *dest, const void *src, size_t len) { if ((uintptr_t)dest <= (uintptr_t)src || (uintptr_t)dest >= (uintptr_t)src + len) { /* Start of destination doesn't overlap source, so just use * memcpy(). */ return memcpy(dest, src, len); } else { /* Need to copy from tail because there is overlap. */ char *d = (char *)dest + len; const char *s = (const char *)src + len; uint32_t *dw; const uint32_t *sw; char *head; char *const tail = (char *)dest; /* Set 'body' to the last word boundary */ uint32_t *const body = (uint32_t *)(((uintptr_t)tail + 3) & ~3); if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { /* Misaligned. no body, no tail. */ head = tail; } else { /* Aligned */ if ((uintptr_t)tail > ((uintptr_t)d & ~3)) /* Shorter than the first word boundary */ head = tail; else /* Set 'head' to the first word boundary */ head = (char *)((uintptr_t)d & ~3); } /* Copy head */ uint32_t head_len = d - head; for (int32_t i = head_len - 1; i >= 0; --i) d[i - head_len] = s[i - head_len]; /* Copy body */ dw = (uint32_t *)(d - head_len); sw = (uint32_t *)(s - head_len); uint32_t body_len = (dw < body) ? 0 : dw - body; for (int32_t i = body_len - 1; i >= 0; --i) dw[i - body_len] = sw[i - body_len]; /* Copy tail */ d = (char *)(dw - body_len); s = (const char *)(sw - body_len); uint32_t tail_len = d - tail; for (int32_t i = tail_len - 1; i >= 0; --i) d[i - tail_len] = s[i - tail_len]; return dest; } } __mram_ptr void * __memmove_mm(__mram_ptr void *dest, __mram_ptr const void *src, size_t len) { if ((uintptr_t)dest <= (uintptr_t)src || (uintptr_t)dest >= (uintptr_t)src + len) { /* Start of destination doesn't overlap source, so just use * memcpy(). */ return (__mram_ptr void *)memcpy(dest, src, len); } else { uint64_t srcCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; uint64_t destCache64[MRAM_CACHE_SIZE / sizeof(uint64_t)]; void *srcCache = (void *)srcCache64; void *destCache = (void *)destCache64; __mram_ptr const void *srcIdx = src + len; __mram_ptr void *dstIdx = dest + len; uint32_t remaining = len; uint32_t srcOff = ((uintptr_t)srcIdx) & DMA_OFF_MASK; uint32_t dstOff = ((uintptr_t)dstIdx) & DMA_OFF_MASK; if (srcOff == dstOff) { size_t part = MIN(remaining, srcOff); uint32_t off = srcOff - part; if (dstOff != 0) { srcIdx -= srcOff; dstIdx -= dstOff; mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + off, srcCache + off, part); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); remaining -= part; } srcIdx -= MRAM_CACHE_SIZE; dstIdx -= MRAM_CACHE_SIZE; while (remaining >= MRAM_CACHE_SIZE) { mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); mram_write(srcCache, dstIdx, MRAM_CACHE_SIZE); remaining -= MRAM_CACHE_SIZE; srcIdx -= MRAM_CACHE_SIZE; dstIdx -= MRAM_CACHE_SIZE; } if (remaining != 0) { uint32_t off = MRAM_CACHE_SIZE - remaining; mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + off, srcCache + off, remaining); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); } } else { size_t initLen = MIN(remaining, MIN(dstOff, srcOff)); if (initLen == remaining) { mram_read(dest, destCache, MRAM_CACHE_SIZE); mram_read(src, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + dstOff - remaining, srcCache + srcOff - remaining, remaining); mram_write(destCache, dest, MRAM_CACHE_SIZE); return dest; } mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; if (dstOff != 0) { size_t part = DMA_ALIGNED(dstOff); mram_read(dstIdx, destCache + MRAM_CACHE_SIZE - part, part); if (srcOff > dstOff) { part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - dstOff); memcpy(destCache, srcCache + srcOff - part, part); srcOff -= part; } else { part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + dstOff - part, srcCache, part); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; size_t part2 = dstOff - part; memcpy(destCache, srcCache + MRAM_CACHE_SIZE - part2, part2); srcOff = MRAM_CACHE_SIZE - part2; } mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); dstIdx -= MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE - (DMA_ALIGNMENT - dstOff); } while (remaining >= MRAM_CACHE_SIZE) { size_t part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + MRAM_CACHE_SIZE - part, srcCache, part); mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); srcIdx -= MRAM_CACHE_SIZE; size_t part2 = MRAM_CACHE_SIZE - part; memcpy(destCache, srcCache + MRAM_CACHE_SIZE - part2, part2); mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); dstIdx -= MRAM_CACHE_SIZE; remaining -= MRAM_CACHE_SIZE; } if (remaining != 0) { mram_read(dstIdx, destCache, MRAM_CACHE_SIZE); size_t part = MRAM_CACHE_SIZE - (DMA_ALIGNMENT - srcOff); memcpy(destCache + MRAM_CACHE_SIZE - part, srcCache, part); if (remaining > part) { size_t part2 = remaining - part; mram_read(srcIdx, srcCache, MRAM_CACHE_SIZE); memcpy(destCache + MRAM_CACHE_SIZE - remaining, srcCache + MRAM_CACHE_SIZE - part2, part2); } mram_write(destCache, dstIdx, MRAM_CACHE_SIZE); } } return dest; } } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memmram_utils.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_MEMMRAM_UTILS_H_ #define _DPUSYSCORE_MEMMRAM_UTILS_H_ #define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define ALIGN(x, a) ALIGN_MASK((x), (a)-1) #define DMA_ALIGNMENT 8 #define DMA_OFF_MASK (DMA_ALIGNMENT - 1) #define DMA_ALIGNED(x) ALIGN(x, DMA_ALIGNMENT) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MRAM_CACHE_SIZE 8 #endif /* _DPUSYSCORE_MEMMRAM_UTILS_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/memset.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include static void * __memset_wram_1align(void *dest, int c, size_t len) { uint8_t *dest8 = (uint8_t *)(dest); for (uint32_t i = 0; i < (len); ++i) { dest8[i] = (c); } return dest; } typedef uint32_t memset_wram_t; /* Requisite: * - dest: align on 4 bytes * - len: mutiple of 4 bytes */ void *__attribute__((used)) __memset_wram_4align(void *dest, int c, size_t len) { uint32_t cccc; memset_wram_t *dest32 = (memset_wram_t *)dest; c &= 0xff; /* Clear upper bits before ORing below */ cccc = c | (c << 8) | (c << 16) | (c << 24); for (uint32_t i = 0; i < len / sizeof(memset_wram_t); ++i) { dest32[i] = cccc; } return dest; } void * memset(void *dest, int c, size_t len) { const uint32_t align = sizeof(memset_wram_t); const uint32_t align_off_mask = (align - 1); uint32_t align_offset = ((uintptr_t)dest) & align_off_mask; uint8_t *d = (uint8_t *)dest; /* memset head */ if (align_offset != 0) { size_t head_len = align - align_offset; if (head_len > len) { head_len = len; } __memset_wram_1align(d, c, head_len); len -= head_len; d += head_len; } /* memset body */ if (len >= align) { size_t body_len = len & (~align_off_mask); __memset_wram_4align(d, c, body_len); len -= body_len; d += body_len; } /* memset tail */ if (len > 0) { __memset_wram_1align(d, c, len); } return dest; } #define MEMSET_MRAM_CACHE_SIZE (8) /* Requisite: * - dest: align on 8 bytes * - len: mutiple of 8 bytes */ __attribute__((used)) __mram_ptr void * __memset_mram_8align(__mram_ptr void *dest, int c, size_t len) { __dma_aligned uint8_t cache64[MEMSET_MRAM_CACHE_SIZE]; void *cache = (void *)cache64; __memset_wram_4align(cache, c, MEMSET_MRAM_CACHE_SIZE); for (uint32_t idx = 0; idx < len; idx += MEMSET_MRAM_CACHE_SIZE) { mram_write(cache, dest + idx, MEMSET_MRAM_CACHE_SIZE); } return dest; } __attribute__((used)) __mram_ptr void * __memset_mram(__mram_ptr void *dest, int c, size_t len) { __dma_aligned uint8_t cache64[MEMSET_MRAM_CACHE_SIZE]; void *cache = (void *)cache64; __mram_ptr uint8_t *d = (__mram_ptr uint8_t *)((uintptr_t)dest & (~DMA_OFF_MASK)); uint32_t align_offset = ((uintptr_t)dest) & DMA_OFF_MASK; /* memset head */ if (align_offset != 0) { size_t head_len = MEMSET_MRAM_CACHE_SIZE - align_offset; if (head_len > len) { head_len = len; } mram_read(d, cache, MEMSET_MRAM_CACHE_SIZE); __memset_wram_1align(cache + align_offset, c, head_len); mram_write(cache, d, MEMSET_MRAM_CACHE_SIZE); len -= head_len; d += MEMSET_MRAM_CACHE_SIZE; } /* memset body */ if (len >= MRAM_CACHE_SIZE) { size_t body_len = len & (~(MEMSET_MRAM_CACHE_SIZE - 1)); __memset_mram_8align(d, c, body_len); len -= body_len; d += body_len; } /* memset tail */ if (len > 0) { mram_read(d, cache, MEMSET_MRAM_CACHE_SIZE); __memset_wram_1align(cache, c, len); mram_write(cache, d, MEMSET_MRAM_CACHE_SIZE); } return dest; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdalign.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDALIGN_H_ #define _DPUSYSCORE_STDALIGN_H_ /** * @file stdalign.h * @brief Defines align macros. */ /** * @def alignas * @brief _Alignas specifier. */ #define alignas _Alignas /** * @def alignof * @brief _Alignof operator. */ #define alignof _Alignof /** * @def __alignas_is_defined * @brief Whether the alignas macro is defined. */ #define __alignas_is_defined 1 /** * @def __alignof_is_defined * @brief Whether the alignof macro is defined. */ #define __alignof_is_defined 1 #endif /* _DPUSYSCORE_STDALIGN_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdarg.h ================================================ /*===---- stdarg.h - Variable argument handling ----------------------------=== * * Copyright (c) 2008 Eli Friedman * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * *===-----------------------------------------------------------------------=== */ #ifndef __STDARG_H #define __STDARG_H #ifndef _VA_LIST typedef __builtin_va_list va_list; #define _VA_LIST #endif #define va_start(ap, param) __builtin_va_start(ap, param) #define va_end(ap) __builtin_va_end(ap) #define va_arg(ap, type) __builtin_va_arg(ap, type) /* GCC always defines __va_copy, but does not define va_copy unless in c99 mode * or -ansi is not specified, since it was not part of C90. */ #define __va_copy(d, s) __builtin_va_copy(d, s) #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__) #define va_copy(dest, src) __builtin_va_copy(dest, src) #endif #ifndef __GNUC_VA_LIST #define __GNUC_VA_LIST 1 typedef __builtin_va_list __gnuc_va_list; #endif #endif /* __STDARG_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdbool.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDBOOL_H_ #define _DPUSYSCORE_STDBOOL_H_ /** * @file stdbool.h * @brief Defines the boolean type. */ /** * @def __bool_true_false_are_defined * @brief Whether the boolean type and values are defined. */ #define __bool_true_false_are_defined 1 /** * @def bool * @brief The boolean type. */ #define bool _Bool /** * @def true * @brief The true constant, represented by 1 */ #define true 1 /** * @def false * @brief The false constant, represented by 0 */ #define false 0 #endif /* _DPUSYSCORE_STDBOOL_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stddef.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDDEF_H_ #define _DPUSYSCORE_STDDEF_H_ /** * @file stddef.h * @brief Defines some standard types. */ /** * @brief The type for the result of subtracting two pointers. */ typedef int ptrdiff_t; /** * @brief The type for the result of the sizeof operator. * * @internal No memory or object in the DPU can be more than megabytes of data. * As a consequence, we can restrict the sizes to 32 bits, which is * already a lot. */ typedef unsigned int size_t; /** * @brief Value whose alignment requirement is at least as strict (as large) as that of every scalar type. */ typedef unsigned long int max_align_t; /** * @brief The type for wide-character codes. */ typedef unsigned int wchar_t; /** * @def NULL * @brief The null pointer constant. */ #define NULL ((void *)0) /** * @def offsetof * @hideinitializer * @brief Offset in bytes to the structure member, from the beginning of its structure. * * @param st the structure * @param m the member name * * @internal Raw version of offsetof, should be enough in our context, with all the underlying risks. */ #define offsetof(st, m) ((size_t)(&((st *)0)->m)) #endif /* _DPUSYSCORE_STDDEF_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdint.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDINT_H_ #define _DPUSYSCORE_STDINT_H_ /** * @file stdint.h * @brief Provides abstraction over machine types. */ /* Exact integer types */ /* Signed */ /** * @brief A signed 8-bit value. */ typedef signed char int8_t; /** * @brief A signed 16-bit value. */ typedef short int int16_t; /** * @brief A signed 32-bit value. */ typedef int int32_t; /** * @brief A signed 64-bit value. */ typedef long long int int64_t; /* Unsigned */ /** * @brief An unsigned 8-bit value. */ typedef unsigned char uint8_t; /** * @brief An unsigned 16-bit value. */ typedef unsigned short int uint16_t; /** * @brief An unsigned 32-bit value. */ typedef unsigned int uint32_t; /** * @brief An unsigned 64-bit value. */ typedef unsigned long int uint64_t; /* Small types */ /* Signed */ /** * @brief A signed value on at least 8 bits. */ typedef signed char int_least8_t; /** * @brief A signed value on at least 16 bits. */ typedef short int int_least16_t; /** * @brief A signed value on at least 32 bits. */ typedef int int_least32_t; /** * @brief A signed value on at least 64 bits. */ typedef long int int_least64_t; /* Unsigned */ /** * @brief An unsigned value on at least 8 bits. */ typedef unsigned char uint_least8_t; /** * @brief An unsigned value on at least 16 bits. */ typedef unsigned short int uint_least16_t; /** * @brief An unsigned value on at least 32 bits. */ typedef unsigned int uint_least32_t; /** * @brief An unsigned value on at least 64 bits. */ typedef unsigned long int uint_least64_t; /* Fast types */ /* Signed */ /** * @brief A signed value on at least 8 bits, optimized for that length. */ typedef signed char int_fast8_t; /** * @brief A signed value on at least 16 bits, optimized for that length. */ typedef int int_fast16_t; /** * @brief A signed value on at least 32 bits, optimized for that length. */ typedef int int_fast32_t; /** * @brief A signed value on at least 64 bits, optimized for that length. */ typedef long int int_fast64_t; /* Unsigned */ /** * @brief An unsigned value on at least 8 bits, optimized for that length. */ typedef unsigned char uint_fast8_t; /** * @brief An unsigned value on at least 16 bits, optimized for that length. */ typedef unsigned int uint_fast16_t; /** * @brief An unsigned value on at least 32 bits, optimized for that length. */ typedef unsigned int uint_fast32_t; /** * @brief An unsigned value on at least 64 bits, optimized for that length. */ typedef unsigned long int uint_fast64_t; /* Types for void* pointers */ /** * @brief A signed value which can contain a pointer value. */ typedef int intptr_t; /** * @brief An unsigned value which can contain a pointer value. */ typedef unsigned int uintptr_t; /* Greatest-width integer types */ /** * @brief A signed value which can contain all signed values. */ typedef long long int intmax_t; /** * @brief An unsigned value which can contain all unsigned values. */ typedef unsigned long long int uintmax_t; #include #endif /* _DPUSYSCORE_STDINT_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdio.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #include #include #define DEFAULT_STDOUT_BUFFER_SIZE (1 << 20) unsigned char __weak __mram_noinit __stdout_buffer[DEFAULT_STDOUT_BUFFER_SIZE]; unsigned int __weak __stdout_buffer_size = DEFAULT_STDOUT_BUFFER_SIZE; /* __lower_data: needed to make sure that the structure address will be less that a signed12 * (sd endian:e ra off:s12 imm:s16 used in bootstrap). * * __dma_aligned: needed to make sure that the structure address will be aligned on 8 bytes (for sd in bootstrap as well). * * This structure is initialize at zero in the bootsrap */ __lower_data(__STR(__STDOUT_BUFFER_STATE)) __dma_aligned struct { uint32_t wp; uint32_t has_wrapped; } __STDOUT_BUFFER_STATE; static uint32_t __stdout_buffer_write_pointer_initial; static uint32_t __stdout_nr_of_wrapping; #define STDOUT_CACHE_BUFFER_SIZE 8 _Static_assert((STDOUT_CACHE_BUFFER_SIZE >= 8) && (STDOUT_CACHE_BUFFER_SIZE <= 2048) && (STDOUT_CACHE_BUFFER_SIZE % 8 == 0), "STDOUT_CACHE_BUFFER_SIZE needs to be a multiple of 8 in ]0; 2048]"); static char __stdout_cache_buffer[STDOUT_CACHE_BUFFER_SIZE] __dma_aligned; static unsigned int __stdout_cache_write_index; ATOMIC_BIT_INIT(__stdout_buffer_lock); __attribute__((noinline)) static void __transfer_cache_to_mram() { __mram_ptr void *offset_in_mram = (__mram_ptr void *)(__STDOUT_BUFFER_STATE.wp + (uintptr_t)__stdout_buffer); __STDOUT_BUFFER_STATE.wp += STDOUT_CACHE_BUFFER_SIZE; if (__STDOUT_BUFFER_STATE.wp >= __stdout_buffer_size) { __STDOUT_BUFFER_STATE.wp = 0; __STDOUT_BUFFER_STATE.has_wrapped = true; __stdout_nr_of_wrapping++; } mram_write(__stdout_cache_buffer, offset_in_mram, STDOUT_CACHE_BUFFER_SIZE); } // Generic template that will be used everywhere: cache a byte and flush to MRAM // when the cache is full. __attribute__((noinline)) static void __write_byte_and_flush_if_needed(uint8_t byte) { __stdout_cache_buffer[__stdout_cache_write_index++] = byte; if (__stdout_cache_write_index == STDOUT_CACHE_BUFFER_SIZE) { __transfer_cache_to_mram(); __stdout_cache_write_index = 0; } } __attribute__((noinline)) static void __finalized_print_sequence() { memset(__stdout_cache_buffer + __stdout_cache_write_index, 0, STDOUT_CACHE_BUFFER_SIZE - __stdout_cache_write_index); __transfer_cache_to_mram(); if (__stdout_nr_of_wrapping > 1 || (__stdout_nr_of_wrapping == 1 && __STDOUT_BUFFER_STATE.wp > __stdout_buffer_write_pointer_initial)) __asm__("fault " __STR(__FAULT_PRINTF_OVERFLOW__)); // need to throw fault because we will not be able to print the buffer } __attribute__((noinline)) static void __open_print_sequence() { ATOMIC_BIT_ACQUIRE(__stdout_buffer_lock); __stdout_cache_write_index = 0; __stdout_nr_of_wrapping = 0; __stdout_buffer_write_pointer_initial = __STDOUT_BUFFER_STATE.wp; } /* Nothing else that the release instruction should be in this function in order to make sure that the print routine in complete * at this point*/ __attribute__((noinline)) static void __close_print_sequence() { ATOMIC_BIT_RELEASE(__stdout_buffer_lock); } void printf(const char *restrict format, ...) { bool insert_string_arg = true; bool insert_string_arg_end_character = false; char *current_format_char_ptr = (char *)format; __open_print_sequence(); va_list args; va_start(args, format); for (; *current_format_char_ptr != '\0'; ++current_format_char_ptr) { if (*current_format_char_ptr == '%') { ++current_format_char_ptr; if (*current_format_char_ptr == '\0') break; if (*current_format_char_ptr == '%') goto standard_character_format_process; __write_byte_and_flush_if_needed('%'); while (*current_format_char_ptr != '\0') { if (*current_format_char_ptr == 'l') { __write_byte_and_flush_if_needed(*current_format_char_ptr); ++current_format_char_ptr; continue; } if ((*current_format_char_ptr == 'L') || (*current_format_char_ptr == 'z')) { ++current_format_char_ptr; continue; } if (*current_format_char_ptr == 'i') { __write_byte_and_flush_if_needed('d'); break; } __write_byte_and_flush_if_needed(*current_format_char_ptr); if (((*current_format_char_ptr >= 'A') && (*current_format_char_ptr <= 'Z')) || ((*current_format_char_ptr >= 'a') && (*current_format_char_ptr <= 'z'))) break; ++current_format_char_ptr; } insert_string_arg = true; } else { standard_character_format_process: if (insert_string_arg) { __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('s'); insert_string_arg = false; } } } __write_byte_and_flush_if_needed('\0'); current_format_char_ptr = (char *)format; for (; *current_format_char_ptr != '\0'; ++current_format_char_ptr) { if (*current_format_char_ptr == '%') { ++current_format_char_ptr; if (*current_format_char_ptr == '\0') break; if (*current_format_char_ptr == '%') goto standard_character_process; if (insert_string_arg_end_character) { insert_string_arg_end_character = false; __write_byte_and_flush_if_needed('\0'); } bool arg_is_64_bits = false; while (*current_format_char_ptr != '\0') { if ((*current_format_char_ptr == 'l') || (*current_format_char_ptr == 'L')) { arg_is_64_bits = true; current_format_char_ptr++; continue; } else if (*current_format_char_ptr == 'z') { current_format_char_ptr++; continue; } if (((*current_format_char_ptr >= 'A') && (*current_format_char_ptr <= 'Z')) || ((*current_format_char_ptr >= 'a') && (*current_format_char_ptr <= 'z'))) break; ++current_format_char_ptr; } switch (*current_format_char_ptr) { case 's': { char *arg = (char *)va_arg(args, int); while (*arg != '\0') { __write_byte_and_flush_if_needed(*arg); arg++; } __write_byte_and_flush_if_needed('\0'); break; } case 'c': { char arg_as_char = (char)va_arg(args, int); __write_byte_and_flush_if_needed(arg_as_char); break; } case 'f': case 'e': case 'E': case 'g': case 'G': { __asm__ volatile("nop"); double val = va_arg(args, double); char *arg = (char *)&val; for (int i = 0; i < 8; i++) { char arg_byte = arg[i]; __write_byte_and_flush_if_needed(arg_byte); } break; } default: { unsigned int arg_size_in_bytes; long val; if (arg_is_64_bits) { val = va_arg(args, long); arg_size_in_bytes = 8; } else { val = (long)va_arg(args, int); arg_size_in_bytes = 4; } char *arg = (char *)&val; for (unsigned int i = 0; i < arg_size_in_bytes; i++) { char arg_byte = arg[i]; __write_byte_and_flush_if_needed(arg_byte); } } } } else { standard_character_process: __write_byte_and_flush_if_needed(*current_format_char_ptr); insert_string_arg_end_character = true; } } if (insert_string_arg_end_character) { __write_byte_and_flush_if_needed('\0'); } va_end(args); __finalized_print_sequence(); __close_print_sequence(); } void puts(const char *str) { __open_print_sequence(); __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('s'); __write_byte_and_flush_if_needed('\0'); for (char *current_char_ptr = (char *)str; *current_char_ptr != '\0'; current_char_ptr++) { __write_byte_and_flush_if_needed(*current_char_ptr); } __write_byte_and_flush_if_needed('\n'); __write_byte_and_flush_if_needed('\0'); __finalized_print_sequence(); __close_print_sequence(); } void putchar(int c) { __open_print_sequence(); __write_byte_and_flush_if_needed('%'); __write_byte_and_flush_if_needed('c'); __write_byte_and_flush_if_needed('\0'); char arg_as_char = (char)c; __write_byte_and_flush_if_needed(arg_as_char); __finalized_print_sequence(); __close_print_sequence(); } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdio.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDIO_H_ #define _DPUSYSCORE_STDIO_H_ #include #include /** * @file stdio.h * @brief Standard input/output library functions. */ /** * @def STDOUT_BUFFER_INIT * @hideinitializer * @brief Declares the stdout buffer. Should be used as when declaring a global variable. * @param size the size of the stdout buffer. Must be a multiple of 8, and greater than 0. */ #define STDOUT_BUFFER_INIT(size) \ _Static_assert((size >= 8) && (((size)&7) == 0), "stdout buffer size must be a multiple of 8 and > 0"); \ unsigned char __dma_aligned __mram_noinit __stdout_buffer[(size)]; \ const unsigned int __stdout_buffer_size = (size); /** * @fn printf * @brief Writes the formatted data in the stdout buffer. * * This function has a prototype close to the one of the standard printf function. * However, the format string comply to the java.util.Formatter format, which is * similar to the printf format, but not quit exactly the same. Date formatter may * produce interpreted results, but they will probably be incorrect. Every format * specifier should reference one and only one of the variadic argument (eg. "%n" * is not supported). * * There is no compile-time check to verify that the format is correct: any other * character in the format string will not be interpreted. * * @param format how the logged data should be formatted * @param ... the different data to be printed */ void __attribute__((format(printf, 1, 2))) printf(const char *restrict format, ...); /** * @fn puts * @brief Writes the string in the stdout buffer. A newline character is appended to the output. * @param str the null-terminated string to be written */ void puts(const char *str); /** * @fn putchar * @brief Writes the character in the stdout buffer. * @param c the character to be written */ void putchar(int c); #endif /* _DPUSYSCORE_STDIO_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdlib.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_STDLIB_H #define DPUSYSCORE_STDLIB_H /** * @file stdlib.h * @brief Elementary standard C functions: calls the system function halt. */ #include #include /** * @def EXIT_FAILURE * @hideinitializer * @brief Unsuccessful termination for exit(). */ #define EXIT_FAILURE 1 /** * @def EXIT_SUCCESS * @hideinitializer * @brief Successful termination for exit(). */ #define EXIT_SUCCESS 0 /** * @brief Aborts the DPU execution triggering a processor fault. */ __NO_RETURN void abort(void); /** * @brief Terminates the invoking tasklet, returning the specified status. */ __NO_RETURN void exit(int status); /** * @brief Get an environment variable, or NULL. In the DPU case, always NULL. */ static inline char * getenv(__attribute__((unused)) const char *name) { return NULL; } /** * @brief Returns the absolute value of the argument. */ static inline int abs(int x) { return (x < 0) ? -x : x; } /** * @brief Returns the absolute value of the argument. */ static inline long int labs(long int x) { return (x < 0) ? -x : x; } /** * @brief Returns the absolute value of the argument. */ static inline long long int llabs(long long int x) { return (x < 0) ? -x : x; } typedef struct { int quot; int rem; } div_t; typedef struct { long int quot; long int rem; } ldiv_t; typedef struct { long long int quot; long long int rem; } lldiv_t; static inline div_t div(int numer, int denom) { div_t result = { numer / denom, numer % denom }; return result; } static inline ldiv_t ldiv(long int numer, long int denom) { ldiv_t result = { numer / denom, numer % denom }; return result; } static inline lldiv_t lldiv(long long int numer, long long int denom) { lldiv_t result = { numer / denom, numer % denom }; return result; } /** * @brief Converts a string to an integer * * Function converts the initial part of the string in nptr to an integer value. The string may begin * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. * * Conversion stops at the first character not representing a digit. If an underflow occurs, atoi() * returns INT_MIN. If an overflow occurs, atoi() returns INT_MAX. In both cases errno is set to ERANGE. * * * @param nptr string that contains an integer in a string format * @return the result of conversion unless the value would overflow or underflow. */ int atoi(const char *nptr); /** * @brief Converts a string to a long integer (64 bits) * * Function converts the initial part of the string in nptr to a long value. The string may begin * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. * * Conversion stops at the first character not representing a digit. If an underflow occurs, atol() * returns LONG_MIN. If an overflow occurs, atol() returns LONG_MAX. In both cases errno is set to ERANGE. * * * @param nptr string that contains an integer in a string format * @return the result of conversion unless the value would overflow or underflow. */ long atol(const char *nptr); ///** // * @brief Converts a string to a long integer (64 bits) according to the given base // * between 2 and 36 inclusive, or be the special value 0 // * // * TODO : If the given base is oustide of the range [2...36], then errno is set to EINVAL // * // * Function converts the initial part of the string in nptr to a long value. The string may begin // * with an arbitrary amount of white space followed by a single optional '+' or '-' sign. // * // * If base is zero or 16, the string may then include a "0x" prefix, and the number will be read // * in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', // * in which case it is taken as 8 (octal). // * // * Conversion stops at the first character not representing a digit in the given base. // * Accepted digits are : in bases above 10, the letter 'A' in either uppercase or lowercase // * represents 10, 'B' represents 11, and so forth, with 'Z' representing 35. // * // * If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. // * If there were no digits at all, strtol() stores the original value of nptr in *endptr (and // * returns 0). In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire // * string is valid. // * // * If an underflow occurs, atol() returns LONG_MIN. If an overflow occurs, atol() // * returns LONG_MAX. TODO!!! In both cases errno is set to ERANGE. // * // * @param nptr string that contains an integer in a string format // * @param endptr // * @param base // // * @return the result of conversion unless the value would overflow or underflow. //*/ // long int strtol(const char *nptr, char **endptr, int base); // TODO : strtol() doesn't work : has to be written in assembly #endif /* DPUSYSCORE_STDLIB_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stdnoreturn.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef _DPUSYSCORE_STDNORETURN_H_ #define _DPUSYSCORE_STDNORETURN_H_ /** * @file stdnoreturn.h * @brief Defines the noreturn macro. */ /** * @def noreturn * @brief _Noreturn attribute. */ #define noreturn _Noreturn #endif /* _DPUSYSCORE_STDNORETURN_H_ */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stpcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ char * stpcpy(char *destination, const char *source) { char c = *source; while (c != '\0') { *destination = c; destination++; source++; c = *source; } *destination = c; return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/stpncpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * stpncpy(char *destination, const char *source, size_t size) { char c = *source; size_t each_byte; for (each_byte = 0; each_byte < size; ++each_byte) { if (c == '\0') { char *null_char_ptr = destination; for (; each_byte < size; ++each_byte) { *destination = '\0'; destination++; } return null_char_ptr; } *destination = c; destination++; source++; c = *source; } return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strcat.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strcat(char *destination, const char *source) { size_t length = strlen(destination); unsigned int i; for (i = 0; source[i] != '\0'; i++) { destination[length + i] = source[i]; } destination[length + i] = '\0'; return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strchr(const char *string, int character) { char *str = (char *)string; unsigned char c = *str; while (1) { if (c == character) { return str; } if (c == '\0') { return NULL; } str++; c = *str; } } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strcmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int strcmp(const char *string1, const char *string2) { unsigned char c1 = *string1; unsigned char c2 = *string2; while (c1 != '\0') { if (c1 - c2 != 0) { return c1 - c2; } string1++; string2++; c1 = *string1; c2 = *string2; } return c1 - c2; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strcpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strcpy(char *destination, const char *source) { char *ptr = destination; char c = *source; while (c != '\0') { *ptr = c; ptr++; source++; c = *source; } *ptr = c; return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strcspn.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include // TODO Possible optimization: // use of the table of indexation that indicates if the character should or should not be accepted/rejected // in this case we will need 128 bits (as there are 128 ascii characters) ( = 16 bytes = 4 words ) per runtime // => 4x24 = 96 words of 32 bits. // // TODO Another solution would be to stock this table only temporarily with the allocation function, but, currently, it's not an // option. size_t strcspn(const char *string, const char *reject) { size_t prefix_length; for (prefix_length = 0; string[prefix_length] != '\0'; ++prefix_length) { char c = string[prefix_length]; for (unsigned int reject_index = 0; reject[reject_index] != '\0'; ++reject_index) { if (reject[reject_index] == c) { return prefix_length; } } } return prefix_length; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strdup.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" #include "buddy_alloc.h" char * strdup(const char *string) { size_t length = strlen(string) + 1; // we get the length of the string for memory allocation char *result = buddy_alloc(length); // we allocate length+1 bytes for the duplicate if (result != NULL) { memcpy(result, string, length); // we copy length bytes from string to the duplicate } return result; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strerror.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include "errno.h" // http://www.delorie.com/gnu/docs/glibc/libc_17.html // static char* strerror_errors[] = { "Success", //"E2BIG", "EACCES", "EADDRINUSE", "EADDRNOTAVAIL", "EAFNOSUPPORT", "EAGAIN", "EALREADY", "EBADF", //"EBADMSG", "EBUSY", "ECANCELED", "ECHILD", "ECONNABORTED", "ECONNREFUSED", "ECONNRESET", "EDEADLK", //"EDESTADDRREQ", "EDOM", "EDQUOT", "EEXIST", "EFAULT", "EFBIG", "EHOSTUNREACH", "EIDRM", //"EILSEQ", "EINPROGRESS", "EINTR", "EINVAL", "EIO", "EISCONN", "EISDIR", "ELOOP", //"EMFILE", "EMLINK", "EMSGSIZE", "EMULTIHOP", "ENAMETOOLONG", "ENETDOWN", "ENETRESET", "ENETUNREACH", //"ENFILE", "ENOBUFS", "ENODATA", "ENODEV", "ENOENT", "ENOEXEC", "ENOLCK", "ENOLINK", //"ENOMEM", "ENOMSG", "ENOPROTOOPT", "ENOSPC", "ENOSR", "ENOSTR", "ENOSYS", "ENOTCONN", //"ENOTDIR", "ENOTEMPTY", "ENOTRECOVERABLE", "ENOTSOCK", "ENOTSUP", "ENOTTY", "ENXIO", "EOPNOTSUPP", //"EOVERFLOW", "EOWNERDEAD", "EPERM", "EPIPE", "EPROTO", "EPROTONOSUPPORT", "EPROTOTYPE", "ERANGE", //"EROFS", "ESPIPE", "ESRCH", "ESTALE", "ETIME", "ETIMEDOUT", "ETXTBSY", "EWOULDBLOCK", //"EXDEV" //}; // 81 errors in total including 2 not supported ones. const static char *strerror_errors_complete[] = { "Success", "Argument list too long", "Permission denied", "Address in use", "Address not available", "Address family not supported", "Resource unavailable, try again", "Connection already in progress", "Bad file descriptor", "Bad message", "Device or resource busy", "Operation canceled", "No child processes", "Connection aborted", "Connection refused", "Connection reset", "Resource deadlock would occur", "Destination address required", "Mathematics argument out of domain of function", "Disk quota exceeded", "File exists", "Bad address", "File too big", "Host unreachable", "Identifier removed", "Illegal byte sequence", "Operation in progress", "Interrupted function", "Invalid argument", "I/O error", "Socket is connected", "File is a directory", "Too many levels of symbolic links", "File descriptor value too large", "Too many links", "Message too large", "EMULTIHOP", "Filename too long", "Network is down", "Connection aborted by network", "Network unreachable", "Too many files open in system", "No buffer space available", "No message is available on the STREAM head read queue", "No such device", "No such file or directory", "Executable file format error", "No locks available", "ENOLINK", "Not enough space", "No message of the desired type", "Protocol unavailable", "No space left on device", "No STREAM resources", "Not a STREAM", "Function not supported", "The socket is not connected", "Not a directory or a symbolic link to a directory", "Directory not empty", "State not recoverable", "Not a socket", "Not supported", "Inappropriate I/O control operation", "No such device or address", "Operation not supported on socket", "Value too large to be stored in data type", "Previous owner died", "Operation not permitted", "Broken pipe", "Protocol error", "Protocol not supported", "Protocol wrong type for socket", "Result too large", "Read-only file system", "Invalid seek", "No such process", "ESTALE", "Stream ioctl() timeout", "Connection timed out", "Text file busy", "Operation would block", "Cross-device link", "Unknown error" }; char * strerror(int errnum) { unsigned int length = sizeof(strerror_errors_complete) / sizeof(strerror_errors_complete[0]) - 1; //-1 for "Unknown error" if (((unsigned int)errnum) >= length) { errno = EINVAL; return (char *)strerror_errors_complete[length]; } return (char *)strerror_errors_complete[errnum]; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/string.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_STRING_H #define DPUSYSCORE_STRING_H /** * @file string.h * @brief Provides functions to manipulate arrays of characters. */ #include /** * @brief Computes the length of the given null-terminated string. * * @param string the string for which we want the length. * @return The length of the string, not including the null character. */ size_t strlen(const char *string); /** * @brief Computes the length of the given null-terminated string if this length is less than max_len. * strnlen checks at most max_len bytes and returns max_len if it has read as many bytes. * * @param string the string for which we want to find the length. * @param max_len maximum number of bytes to check * @return The length of the string, not including the null character or max_len if null character * wasn't found. */ size_t strnlen(const char *string, size_t max_len); /** * @brief Compares the first size bytes of area1 and area2. * * @param area1 the pointer to the start of the first area of the comparison * @param area2 the pointer to the start of the second area of the comparison * @param size the number of bytes to compare between each area. * @return 0 if the areas are the same, a non-zero value otherwise. */ int memcmp(const void *area1, const void *area2, size_t size); /** * @brief Compares the two null-terminated strings string1 and string2. * * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @return 0 if the strings are the same, a non-zero value otherwise. */ int strcmp(const char *string1, const char *string2); /** * @brief Compares the first size bytes of the two null-terminated strings string1 and * string2. * * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @param size the maximum number of bytes to compare between each string. * @return 0 if the strings are the same, a non-zero value otherwise. */ int strncmp(const char *string1, const char *string2, size_t size); /** * @brief Set the first size bytes of area at value. * * @param area the pointer to the start of the area to set * @param value the value at which the area is set * @param size the number of bytes being set * @return A pointer to the start of the set area. */ void * memset(void *area, int value, size_t size); /** * @brief Search for the first occurrence of character in the first size bytes of area. * * @param area the pointer to the start of the area to search * @param character the value to search for * @param size the number of bytes to search * @return A pointer to the first occurrence, if it exists, NULL otherwise. */ void * memchr(const void *area, int character, size_t size); /** * @brief Concatenate the string source after the string destination. * * @param destination the pointer to the start of the first string * @param source the pointer to the start of the second string * @return A pointer to the start of the concatenated string. */ char * strcat(char *destination, const char *source); /** * @brief Concatenate the first size bytes of the string source after the string * destination. * * @param destination the pointer to the start of the first string * @param source the pointer to the start of the second string * @param size the maximum number of bytes to concatenate * @return A pointer to the start of the concatenated string. */ char * strncat(char *destination, const char *source, size_t size); /** * @brief Search for the first occurrence of character in the string. * * @param string the pointer to the start of the string to search * @param character the value to search for * @return A pointer to the first occurrence, if it exists, NULL otherwise. */ char * strchr(const char *string, int character); /** * @brief Search for the last occurrence of character in the string. * * @param string the pointer to the start of the string to search * @param character the value to search for * @return A pointer to the last occurrence, if it exists, NULL otherwise. */ char * strrchr(const char *string, int character); /** * @brief Copy size bytes from source into destination. * * @warning This function is not safe for overlapping memory blocks. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the area to copy * @param size the number of bytes to copy * @return A pointer to the start of the copied area. */ void * memcpy(void *destination, const void *source, size_t size); /** * @brief Copy size bytes from source into destination. * * This is a safer method than memcpy for overlapping memory blocks. * * @see memcpy * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the area to copy * @param size the number of bytes to copy * @return A pointer to the start of the copied area. */ void * memmove(void *destination, const void *source, size_t size); /** * @brief Copy the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @return A pointer to the start of the copied string. */ char * strcpy(char *destination, const char *source); /** * @brief Copy size bytes from the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the start of the copied string. */ char * strncpy(char *destination, const char *source, size_t size); /** * @def strxfrm * @hideinitializer * @brief Transform the first size bytes of the string source into current locale and place them in the * string destination. * * There is no concept of "locale" in the DPU, implying that the related functions behave as native, "locale-less", functions. * This function is just a synonym of strncpy. * * @warning This function is not safe for overlapping strings. * * @see strncpy * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the start of the copied string. */ #define strxfrm strncpy /** * @def strcoll * @hideinitializer * @brief Compare two null-terminated strings using the current locale. * * There is no concept of "locale" in the DPU, implying that the related functions behave as native, "locale-less", functions. * This function is just a synonym of strcmp. * * @see strcmp * @param string1 the pointer to the start of the first string of the comparison * @param string2 the pointer to the start of the second string of the comparison * @return 0 if the strings are the same, a non-zero value otherwise. */ #define strcoll strcmp /** * @brief Copy the string source into the string destination. * * @warning This function is not safe for overlapping strings. * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @return A pointer to the end (the address of the terminating null byte) * of the copied string. */ char * stpcpy(char *destination, const char *source); /** * @brief Copy size bytes from the string source into the stringdestination. * * @warning This function is not safe for overlapping strings. * If size is less than the length of the source, then * the remaining characters in destination will be filled with '\0' * * @param destination the pointer to the start of the destination of the copy * @param source the pointer to the start of the string to copy * @param size the maximum number of bytes to copy * @return A pointer to the end (the address of the terminating null byte) * of the copied string. */ char * stpncpy(char *destination, const char *source, size_t size); /** * @brief Converts every character of a null-terminated string into lowercase * * Convertion is done in place. Only uppercase latin characters * will become lowercase, all other characters will remain * the same. * * @param string the string we want to convert to lowercase. * @return The same pointer as the one passed in parameters */ char * strlwr(char *string); /** * @brief Converts every character of a null-terminated string into lowercase * * Convertion is done in place. Only uppercase latin characters * will become lowercase, all other characters will remain * the same. * * @param string the string we want to convert to lowercase. * @return The same pointer as the one passed in parameters */ char * strupr(char *string); /** * @brief Reverses the order of characters in the string * * For example, a string "Hello" becomes "olleH". The NULL character at the end * of the string remains at the end. * * @param string the string we want to reverse * @return The same pointer as the one passed in parameters */ char * strrev(char *string); /** * @brief Returns a string corresponding to the error number * * Warning : the returned pointer should be duplicated if the user ever needs to modify it * * @param errnum number of error * @return the pointer to the message corresponding to the errnum or NULL if none was found */ char * strerror(int errnum); /** * @brief Returns a pointer to a new string which is a duplicate of the argument * * Warning : Memory for the new string is obtained with buddy_alloc() //TODO buddy_alloc/malloc for now? * and should be freed with buddy_free(). * buddy_init() should be called before calling strerror(). * * @param string string to duplicate * @return the pointer to the duplicate of the argument string or NULL if couldn't allocate enough memory space */ // char *strdup(const char *string); /** * @brief Returns a pointer to a new string which is a duplicate of the argument (copies at most n bytes) * * Warning : Memory for the new string is obtained with buddy_alloc() //TODO buddy_alloc/malloc for now? * and should be freed with buddy_free(). * buddy_init() should be called before calling strerror(). * * @param string string to duplicate * @param n max number of characters to duplicate * @return the pointer to the duplicate of the argument string or NULL if couldn't allocate enough memory space */ // char *strndup(const char *string, size_t n); /** * @brief Calculates the length of the longest prefix of string which consists entirely of bytes in accept. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param accept key characters that the longest prefix consists of * @return the index of the first character in string that is not in accept */ size_t strspn(const char *string, const char *accept); /** * @brief Calculates the length of the longest prefix of string which consists entirely of bytes not in reject. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param reject key characters that must not be in the longest prefix * @return the index of the first character in string that is the same as any of the ones in reject */ size_t strcspn(const char *string, const char *reject); /** * @brief Locates the first occurrence in the target string of any of the bytes in the string accept. * * The function does not sort the characters and does not delete the double occurrences in accept. * If the user wishes to accelerate the function, she/he needs to do this separately. * This decision was made, because the usefulness of such operations highly depends on the parameters. * * @param string the target of the function * @param accept key characters * @return a pointer to the byte in string that matches one of the bytes in accept, or NULL if no such byte is found. */ char * strpbrk(const char *string, const char *accept); /** * @brief Finds the first occurrence of the substring needle in the string haystack. * * If needle is an empty string, the result will be the same pointer as the one passed to haystack * This function uses KMP algorithm, and thereby uses more memory space * * @param haystack the target string where we look for a pattern * @param needle pattern to look for * @return a pointer to the beginning of the located substring, or NULL if the substring is not found */ char * strstr(const char *haystack, const char *needle); /** * @brief Extracts a token from a string * * The strtok_r() function breaks a string into a sequence of zero or more nonempty tokens. * * On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored (modified * internally). In each subsequent call that should parse the same string, str must be NULL and saveptr should be unchanged since * the previous call. * * The caller may specify different strings in delim in successive calls that parse the same string. For instance, if string is * "a,b,c d e f,g", by calling strtok_r() only with "," delimiter will create 4 tokens, but if the user calls it 2 times with "," * delimiter and then the rest with " " delimiter, 6 tokens wil be created : "a","b","c","d","e","f,g" ("f,g" is indeed one token * as strtok_r() was called with " " delimiter). * * Each call to strtok_r() returns a pointer to a null-terminated string containing the next token. This string does not include * the delimiting byte. If no more tokens are found, strtok_r() returns NULL. * * A sequence of calls to strtok_r() that operate on the same string maintains a pointer that determines the point from which to * start searching for the next token. The first call to strtok_r() sets this pointer to point to the first byte of the string. * The start of the next token is determined by scanning forward for the next nondelimiter byte in str. If such a byte is found, * it is taken as the start of the next token. If no such byte is found, then there are no more tokens, and strtok_r() returns * NULL. (A string that is empty or that contains only delimiters will thus cause strtok() to return NULL on the first call.) * * The end of each token is found by scanning forward until either the next delimiter byte is found or until the terminating null * byte ('\0') is encountered. If a delimiter byte is found, it is OVERWRITTEN with a null byte to terminate the current token, * and strtok_r() saves a pointer to the following byte; that pointer will be used as the starting point when searching for the * next token. In this case, strtok_r() returns a pointer to the start of the found token. * * From the above description, it follows that a sequence of two or more contiguous delimiter bytes in the parsed string is * considered to be a single delimiter, and that delimiter bytes at the start or end of the string are ignored. Put another way: * the tokens returned by strtok() are always nonempty strings. * * Different strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr arguments. * * Warning : * strtok_r modifies str * identity of delimiter bytes is lost (i.e. most of them will be replaced by '\0' in str) * if NULL is passed as the first argument for the FIRST call, *saveptr (not saveptr) should also be NULL * * @param str string to extract tokens from * @param delim string that contains bytes that would serve as delimiters * @param saveptr pointer used internally by strtok_r in order to maintain context between successive calls that parse the same * string * @return a pointer to the beginning of the next token terminated by '\0' or NULL if there are no more tokens */ char * strtok_r(char *str, const char *delim, char **saveptr); /** * @brief Extracts a token from a string * * If *stringp is NULL, the strsep() function returns NULL and does nothing else. Otherwise, this function finds the first token * in the string *stringp, that is delimited by one of the bytes in the string delim. This token is terminated by overwriting the * delimiter with a null byte ('\0'), and *stringp is updated to point past the token. In case no delimiter was found, the token * is taken to be the entire string *stringp, and *stringp is made NULL. * * Warning: * strsep() modifies its first parameter * identity of delimiter bytes is lost (they will be replaced by '\0' in *stringp) * * @param stringp pointer to a string (because string will be modified) to extract tokens from * @param delim string that contains bytes that would serve as delimiters * @return a pointer to the found null-terminated token, that is, it returns the original value of *stringp */ char * strsep(char **stringp, const char *delim); #endif /* DPUSYSCORE_STRING_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strlen.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include size_t strlen(const char *string) { const char *ptr = string; while (*ptr != '\0') { ptr++; } return ptr - string; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strlwr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strlwr(char *string) { char *ptr = string; char c; while ((c = *ptr) != '\0') { *ptr = tolower(c); ptr++; } return string; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strncat.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strncat(char *destination, const char *source, size_t size) { size_t length = strlen(destination); size_t i; for (i = 0; (i < size) && (source[i] != '\0'); i++) { destination[length + i] = source[i]; } destination[length + i] = '\0'; return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strncmp.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int strncmp(const char *string1, const char *string2, size_t size) { for (size_t len = 0; len < size; ++len) { unsigned char c1 = string1[len]; unsigned char c2 = string2[len]; if (((c1 - c2) != 0) || (c1 == '\0')) { return c1 - c2; } } return 0; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strncpy.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strncpy(char *destination, const char *source, size_t size) { char *ptr = destination; char c = *source; size_t each_byte; for (each_byte = 0; each_byte < size; ++each_byte) { if (c == '\0') { for (; each_byte < size; ++each_byte) { *ptr = '\0'; ptr++; } return destination; } *ptr = c; ptr++; source++; c = *source; } return destination; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strndup.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" #include "buddy_alloc.h" char * strndup(const char *string, size_t n) { size_t length = strnlen(string, n); char *result = buddy_alloc(length + 1); if (result != NULL) { memcpy(result, string, length); ((char *)result)[length + 1] = '\0'; } return result; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strnlen.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include size_t strnlen(const char *string, size_t max_len) { size_t len = 0; while ((string[len] != '\0') && len < max_len) { len++; } return len; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strpbrk.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include char * strpbrk(const char *string, const char *accept) { string += strcspn(string, accept); return *string ? (char *)string : NULL; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strrchr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strrchr(char *string, int character) { char *pos = NULL; char *ptr = string; unsigned char c; do { c = *ptr; if (c == character) { pos = ptr; } ptr++; } while (c != '\0'); return pos; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strrev.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strrev(char *string) { size_t length = strlen(string); for (size_t each_char = 0; each_char < length / 2; ++each_char) { char c = string[each_char]; string[each_char] = string[length - each_char - 1]; string[length - each_char - 1] = c; } return string; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strsep.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strsep(char **stringp, const char *delim) { if (*stringp == NULL) { return NULL; } char *original = *stringp; char *delim_ptr = strpbrk(*stringp, delim); if (delim_ptr == NULL) { *stringp = NULL; } else { *delim_ptr = '\0'; *stringp = delim_ptr + 1; } return original; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strspn.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include // TODO Possible optimization: // use of the table of indexation that indicates if the character should or should not be accepted/rejected // in this case we will need 128 bits (as there are 128 ascii characters) ( = 16 bytes = 4 words ) per runtime // => 4x24 = 96 words of 32 bits. // // TODO Another solution would be to stock this table only temporarily with the allocation function, but, currently, it's not an // option. size_t strspn(const char *string, const char *accept) { size_t prefix_length; for (prefix_length = 0; string[prefix_length] != '\0'; ++prefix_length) { char c = string[prefix_length]; unsigned int accept_index = 0; while (true) { char a = accept[accept_index]; if (c == a) { break; } if (a == '\0') { return prefix_length; } accept_index++; } } return prefix_length; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strstr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "stdbool.h" #include "string.h" #include "buddy_alloc.h" char * strstr(const char *haystack, const char *needle) { char *current_needle = (char *)needle; char *start_haystack = (char *)haystack; char *current_haystack = start_haystack; while (true) { char needle_char = *current_needle; if (needle_char == '\0') { return start_haystack; } char haystack_char = *current_haystack; if (haystack_char == needle_char) { current_haystack++; current_needle++; } else if (haystack_char == '\0') { return NULL; } else { current_needle = (char *)needle; current_haystack = ++start_haystack; } } } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strtok_r.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "string.h" char * strtok_r(char *str, const char *delim, char **saveptr) { char *end; if (str == NULL) { str = *saveptr; } if (*str == '\0') { *saveptr = str; return NULL; } str += strspn(str, delim); if (*str == '\0') { *saveptr = str; return NULL; } end = str + strcspn(str, delim); if (*end == '\0') { *saveptr = end; return str; } *end = '\0'; *saveptr = end + 1; return str; } ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strtol.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ //// //////TODO : **endptr //// ////#include ////#include "ctype.h" ////#include "limits.h" //// ////static long overflow(int sign) ////{ //// if(sign) //// return INT64_MAX; //// else //// return INT64_MIN; //// //// ////} //// ////long strtol(const char *nptr, char **endptr, int base) ////{ //// if(nptr == NULL) //// return 0; //// unsigned long result = 0; //// int sign = 1; //// int i = 0; ////// while(isspace(nptr[i])) ////// i++; //// ////// switch(nptr[i]){ ////// case '-' : ////// sign = 0; //we change sign only when '-' was encountered ////// case '+' : ////// i++; //we increment i in both cases ////// } //// ////// ////// if((base == 16 ) && (nptr[i] == '0') && (nptr[i+1] == 'x')) ////// i+=2; ////// else if(base == 0){ ////// if(nptr[i] == '0'){ ////// base = 8; ////// i++; ////// if(nptr[i+1] == 'x'){ ////// base = 16; ////// i++; ////// } ////// } ////// else ////// base = 10; ////// } //// ////// switch(base) { ////// case 10 : //// while(((nptr[i]>>4) == 0x3) && ((nptr[i] & 0xf)<=9)){ //// if((unsigned long)result>>60){ //// return overflow(sign); //// } //// //// result = (unsigned long)(result<<1) + (unsigned long)(result<<3) + (unsigned long) nptr[i] - (unsigned long) ///'0'; ////// if((unsigned long)result>>63){ ////// return overflow(sign); ////// } //// i++; //// } ////// break; ////// case 2 : ////// while((nptr[i] & 0xfe) == 0x30){ ////// result = (result<<1) + (unsigned long)(nptr[i] & 0x1); ////// i++; ////// } ////// break; ////// case 4 : ////// while((nptr[i] & 0xfc) == 0x30){ ////// result = (result<<2) + (unsigned long)(nptr[i] & 0x3); ////// i++; ////// } ////// break; ////// case 8 : ////// while((nptr[i] & 0xf8) == 0x30){ ////// result = (result<<3) + (unsigned long)(nptr[i] & 0x7); ////// i++; ////// } ////// break; ////// case 16 : ////// while(((nptr[i]>='0') && (nptr[i]<='9')) || ((nptr[i]>='a') && (nptr[i]<='f')) || ((nptr[i]>='A') && ///(nptr[i]<='F')) ){ ////// unsigned long digit = ((nptr[i]>='0') && (nptr[i]<='9')) ? (unsigned long)(nptr[i] - '0') : (unsigned /// long)((nptr[i] & 0xf) + 10); ////// result = result<<4; ////// result = result + digit; ////// i++; ////// } ////// break; ////// default : ////// if(base < 2 || base > 36){ //base 0 has already been replaced by 8,10 or 16 ////// //TODO!!! ////// break; ////// } ////// } //// ////// if(sign == 0) ////// return (long)0 - (long)result; ////// else //// return (long) result; //// ////} //// // // // //// // //// Copyright (c) 2014-2019 - UPMEM // //// // //#include // //#include "limits.h" // //#include "ctype.h" // // static long overflow(int sign) // //{ // // if(sign) // // return INT64_MAX; // // else // // return INT64_MIN; // //} // // long int strtol(const char *nptr, char **endptr, int base) // //{ // // if(nptr == NULL) // // return 0; // // int sign = 1; // // int i=0; // // long result = 0; // // // // while((nptr[i]>='0') && (nptr[i]<='9')){ // // if(result>>60){ // // return overflow(sign); // // } // // result = (result<<1) + (result<<3)+ nptr[i] - '0'; // // i++; // // } // // return result; // //} ================================================ FILE: golang_vm/uPIMulator/sdk/stdlib/strupr.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include char * strupr(char *string) { char *ptr = string; char c; while ((c = *ptr) != '\0') { *ptr = toupper(c); ptr++; } return string; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/CMakeLists.txt ================================================ set(CMAKE_C_COMPILER "/root/upmem-2023.2.0-Linux-x86_64/bin/dpu-upmem-dpurte-clang") set(CMAKE_C_FLAGS "-O3 -S -DNR_TASKLETS=${NR_TASKLETS}") include_directories("/root/uPIMulator/sdk/misc") include_directories("/root/uPIMulator/sdk/stdlib") include_directories("/root/uPIMulator/sdk/syslib") file(GLOB_RECURSE SRCS *.c) add_library(syslib ${SRCS}) ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/absvdi2.c ================================================ /*===-- absvdi2.c - Implement __absvdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __absvdi2 for the compiler_rt library. * *===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: absolute value */ /* Effects: aborts if abs(x) < 0 */ COMPILER_RT_ABI di_int __absvdi2(di_int a) { const int N = (int)(sizeof(di_int) * CHAR_BIT); if (a == ((di_int)1 << (N - 1))) compilerrt_abort(); const di_int t = a >> (N - 1); return (a ^ t) - t; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/absvsi2.c ================================================ /* ===-- absvsi2.c - Implement __absvsi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __absvsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: absolute value */ /* Effects: aborts if abs(x) < 0 */ COMPILER_RT_ABI si_int __absvsi2(si_int a) { const int N = (int)(sizeof(si_int) * CHAR_BIT); if (a == (1 << (N - 1))) compilerrt_abort(); const si_int t = a >> (N - 1); return (a ^ t) - t; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/adddf3.c ================================================ //===-- lib/adddf3.c - Double-precision addition ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float addition with the IEEE-754 // default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_add_impl.inc" COMPILER_RT_ABI double __adddf3(double a, double b) { return __addXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_dadd(double a, double b) { return __adddf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/addsf3.c ================================================ //===-- lib/addsf3.c - Single-precision addition ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float addition with the IEEE-754 // default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_add_impl.inc" COMPILER_RT_ABI float __addsf3(float a, float b) { return __addXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_fadd(float a, float b) { return __addsf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/addvdi3.c ================================================ /* ===-- addvdi3.c - Implement __addvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __addvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a + b */ /* Effects: aborts if a + b overflows */ COMPILER_RT_ABI di_int __addvdi3(di_int a, di_int b) { di_int s = (du_int)a + (du_int)b; if (b >= 0) { if (s < a) compilerrt_abort(); } else { if (s >= a) compilerrt_abort(); } return s; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/addvsi3.c ================================================ /* ===-- addvsi3.c - Implement __addvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __addvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a + b */ /* Effects: aborts if a + b overflows */ COMPILER_RT_ABI si_int __addvsi3(si_int a, si_int b) { si_int s = (su_int)a + (su_int)b; if (b >= 0) { if (s < a) compilerrt_abort(); } else { if (s >= a) compilerrt_abort(); } return s; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/alloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include volatile unsigned int __sys_heap_pointer = (unsigned int)(&__sys_heap_pointer_reset); ATOMIC_BIT_INIT(__heap_pointer); /* noinline, because part of grind tracked functions * Also used by seqread.inc */ void *__noinline mem_alloc_nolock(size_t size) { unsigned int pointer = __HEAP_POINTER; if (size != 0) { pointer = (pointer + 7) & ~7; unsigned int new_heap_pointer, dummy; __asm__ volatile("\tadd %[nhp], %[ptr], %[sz], nc, . + 2\n" "\tfault " __STR(__FAULT_ALLOC_HEAP_FULL__) "\n" "\tlbu %[dumb], %[nhp], -1\n" : [nhp] "=r"(new_heap_pointer), [dumb] "=r"(dummy) : [ptr] "r"(pointer), [sz] "r"(size)); __HEAP_POINTER = new_heap_pointer; } return (void *)pointer; } void * mem_alloc(size_t size) { ATOMIC_BIT_ACQUIRE(__heap_pointer); void *pointer = mem_alloc_nolock(size); ATOMIC_BIT_RELEASE(__heap_pointer); return pointer; } void * mem_reset() { ATOMIC_BIT_ACQUIRE(__heap_pointer); void *initial = &__sys_heap_pointer_reset; __sys_heap_pointer = (unsigned int)initial; ATOMIC_BIT_RELEASE(__heap_pointer); return (void *)initial; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/alloc.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ALLOC_H #define DPUSYSCORE_ALLOC_H /** * @file alloc.h * @brief Provides a way to manage heap allocation. * * @internal The heap is situated after the different kernel structures, local and global variables. * It can grow until reaching the end of the WRAM. A reboot of the DPU reset the Heap. * The current heap pointer can be accessed at the address defined by __HEAP_POINTER__. */ #include #include #include #include /** * @fn mem_alloc * @brief Allocates a buffer of the given size in the heap. * * The allocated buffer is aligned on 64 bits, in order to ensure compatibility * with the maximum buffer alignment constraint. As a consequence, a buffer * allocated with this function is also compatible with data transfers to/from MRAM. * * @param size the allocated buffer's size, in bytes * @throws a fault if there is no memory left * @return The allocated buffer address. */ void * mem_alloc(size_t size); /** * @fn mem_reset * @brief Resets the heap. * * Every allocated buffer becomes invalid, since subsequent allocations restart from the beginning * of the heap. * * @return The heap initial address. */ void * mem_reset(void); #endif /* DPUSYSCORE_ALLOC_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ashldi3.c ================================================ /* ====-- ashldi3.c - Implement __ashldi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ashldi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a << b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __ashldi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); dwords input; dwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { result.s.low = 0; result.s.high = input.s.low << (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.low = input.s.low << b; result.s.high = (input.s.high << b) | (input.s.low >> (bits_in_word - b)); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_llsl(di_int a, si_int b) { return __ashldi3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ashrdi3.c ================================================ /*===-- ashrdi3.c - Implement __ashrdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ashrdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: arithmetic a >> b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __ashrdi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); dwords input; dwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { /* result.s.high = input.s.high < 0 ? -1 : 0 */ result.s.high = input.s.high >> (bits_in_word - 1); result.s.low = input.s.high >> (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.high = input.s.high >> b; result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_lasr(di_int a, si_int b) { return __ashrdi3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/atomic_bit.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ATOMIC_BIT_H #define DPUSYSCORE_ATOMIC_BIT_H /** * @file atomic_bit.h * @brief Provides direct access to the atomic bits. */ #include #include #include #define ATOMIC_BIT_GET(_name) __CONCAT(__atomic_bit_, _name) #define ATOMIC_BIT_INIT(_name) uint8_t __atomic_bit ATOMIC_BIT_GET(_name) #define ATOMIC_BIT_EXTERN(_name) extern ATOMIC_BIT_INIT(_name) extern uint8_t __atomic_start_addr; #define ATOMIC_BIT_INDEX(_name) (&ATOMIC_BIT_GET(_name) - &__atomic_start_addr) #define __ATOMIC_BIT_ACQUIRE(_reg, _bit) \ __asm__ volatile("acquire %[areg], %[abit], nz, ." : : [areg] "r"(_reg), [abit] "i"(_bit)) #define __ATOMIC_BIT_RELEASE(_reg, _bit) \ __asm__ volatile("release %[areg], %[abit], nz, .+1" : : [areg] "r"(_reg), [abit] "i"(_bit)) #define ATOMIC_BIT_ACQUIRE(_name) __asm__ volatile("acquire zero, %[abit], nz, ." : : [abit] "i"(&ATOMIC_BIT_GET(_name))) #define ATOMIC_BIT_RELEASE(_name) __asm__ volatile("release zero, %[abit], nz, .+1" : : [abit] "i"(&ATOMIC_BIT_GET(_name))) #endif /* DPUSYSCORE_ATOMIC_BIT_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/atomics.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * Prototype of function can be found here: https://llvm.org/docs/Atomics.html */ #include #include #define ATOMIC_BIT llvm_atomic_functions ATOMIC_BIT_INIT(ATOMIC_BIT); #define FOR_ALL_TYPES(fct) fct(1, char) fct(2, short) fct(4, int) fct(8, long long) #define PROLOGUE(ptr, load, n_type) \ n_type load; \ ATOMIC_BIT_ACQUIRE(ATOMIC_BIT); \ load = *ptr; #define EPILOGUE(load) \ ATOMIC_BIT_RELEASE(ATOMIC_BIT); \ return load; #define __SYNC_VAL_COMPARE_AND_SWAP_N(n_val, n_type) \ n_type __dpu_sync_val_compare_and_swap_##n_val(volatile n_type *ptr, n_type expected, n_type desired) \ { \ PROLOGUE(ptr, load, n_type); \ if (load == expected) \ *ptr = desired; \ EPILOGUE(load); \ } FOR_ALL_TYPES(__SYNC_VAL_COMPARE_AND_SWAP_N) #define __SYNC_LOCK_TEST_AND_SET_N(n_val, n_type) \ n_type __dpu_sync_lock_test_and_set_##n_val(volatile n_type *ptr, n_type val) \ { \ PROLOGUE(ptr, load, n_type); \ *ptr = val; \ EPILOGUE(load); \ } FOR_ALL_TYPES(__SYNC_LOCK_TEST_AND_SET_N) #define __SYNC_FETCH_AND_DO_N(fct, fct_name, n_val, n_type) \ n_type __dpu_sync_fetch_and_##fct_name##_##n_val(volatile n_type *ptr, n_type val) \ { \ PROLOGUE(ptr, load, n_type); \ *ptr = fct(load, val, n_type); \ EPILOGUE(load); \ } #define DO_ADD(a, b, n_type) ((a) + (b)) #define __SYNC_FETCH_AND_ADD_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_ADD, add, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_ADD_N) #define DO_SUB(a, b, n_type) ((a) - (b)) #define __SYNC_FETCH_AND_SUB_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_SUB, sub, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_SUB_N) #define DO_AND(a, b, n_type) ((a) & (b)) #define __SYNC_FETCH_AND_AND_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_AND, and, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_AND_N) #define DO_OR(a, b, n_type) ((a) | (b)) #define __SYNC_FETCH_AND_OR_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_OR, or, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_OR_N) #define DO_XOR(a, b, n_type) ((a) ^ (b)) #define __SYNC_FETCH_AND_XOR_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_XOR, xor, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_XOR_N) #define DO_NAND(a, b, n_type) (~((a) & (b))) #define __SYNC_FETCH_AND_NAND_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_NAND, nand, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_NAND_N) #define DO_MAX(a, b, n_type) ((a) > (b) ? (a) : (b)) #define __SYNC_FETCH_AND_MAX_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_MAX, max, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_MAX_N) #define DO_UMAX(a, b, n_type) (((unsigned n_type)(a)) > ((unsigned n_type)(b)) ? (a) : (b)) #define __SYNC_FETCH_AND_UMAX_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_UMAX, umax, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_UMAX_N) #define DO_MIN(a, b, n_type) ((a) > (b) ? (a) : (b)) #define __SYNC_FETCH_AND_MIN_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_MIN, min, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_MIN_N) #define DO_UMIN(a, b, n_type) (((unsigned n_type)(a)) > ((unsigned n_type)(b)) ? (a) : (b)) #define __SYNC_FETCH_AND_UMIN_N(n_val, n_type) __SYNC_FETCH_AND_DO_N(DO_UMIN, umin, n_val, n_type) FOR_ALL_TYPES(__SYNC_FETCH_AND_UMIN_N) ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/attributes.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_ATTRIBUTES_H #define DPUSYSCORE_ATTRIBUTES_H /** * @file attributes.h * @brief Provides common useful compiler attributes. */ #define DEPRECATED __attribute__((deprecated)) #if __STDC_VERSION__ >= 201112L #define __NO_RETURN _Noreturn #else #define __NO_RETURN #endif /* __STDC_VERSION__ */ #define __weak __attribute__((weak)) #define __section(s) __attribute__((section(s))) #define __aligned(a) __attribute__((aligned(a))) #define __used __attribute__((used)) #define __noinline __attribute__((noinline)) #define __atomic_bit __section(".atomic") #define __dma_aligned __aligned(8) #define __keep __used __section(".data.__sys_keep") #define __host __aligned(8) __used __section(".dpu_host") // Use this macro at variable definition to place this variable into the section // .data.immediate_memory and then makes it possible to use this variable // directly as an immediate into load store instructions (and then avoids the need // to move the address into a register before): immediate values are 12 signed bits // large. #define __lower_data(name) __attribute__((used, section(".data.immediate_memory." name))) /** * @def __mram_ptr * @brief An attribute declaring that a pointer is an address in MRAM. * * A typical usage is: ``unsigned int __mram_ptr * array32 = (unsigned int __mram_ptr *) 0xf000;`` * * Performing a cast between a pointer in MRAM and a pointer in WRAM is not allowed by the compiler. * */ #define __mram_ptr __attribute__((address_space(255))) #define __mram __mram_ptr __section(".mram") __dma_aligned __used #define __mram_noinit __mram_ptr __section(".mram.noinit") __dma_aligned __used #define __mram_keep __mram_ptr __section(".mram.keep") __dma_aligned __used #define __mram_noinit_keep __mram_ptr __section(".mram.noinit.keep") __dma_aligned __used #endif /* DPUSYSCORE_ATTRIBUTES_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/barrier.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include void barrier_wait(struct barrier_t *barrier) { unsigned char lock = barrier->lock; __acquire(lock, "0"); unsigned char count = barrier->count; unsigned char last = barrier->wait_queue; unsigned char first; thread_id_t tid = me(); /* Count = 1 means that I am the last to enter the barrier. * Need to wake up everybody.*/ if (unlikely(count == 1)) { if (likely(last != __EMPTY_WAIT_QUEUE)) { first = __WAIT_QUEUE_TABLE[last]; while (first != last) { __resume(first, "0"); first = __WAIT_QUEUE_TABLE[first]; } __resume(first, "0"); barrier->wait_queue = __EMPTY_WAIT_QUEUE; barrier->count = barrier->initial_count; } __release(lock, "0", __AT_NEXT_INSTRUCTION); } else { if (unlikely(last == __EMPTY_WAIT_QUEUE)) { __WAIT_QUEUE_TABLE[tid] = tid; } else { first = __WAIT_QUEUE_TABLE[last]; __WAIT_QUEUE_TABLE[tid] = first; __WAIT_QUEUE_TABLE[last] = tid; } barrier->wait_queue = tid; barrier->count = --count; __release(lock, "0", __AT_NEXT_INSTRUCTION); __stop(); } } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/barrier.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_BARRIER_H #define DPUSYSCORE_BARRIER_H /** * @file barrier.h * @brief Synchronization with barriers. * * This synchronization mechanism allows to suspend a fixed number of tasklets until the expected number of subscribers is * present. When the required number of tasklets reached the barrier, the counter of the barrier will be reinitialised to the * original value. * * @internal The barriers are represented by a static value, defining the number of expected tasklets, a counter for the * current number of tasklets suspended by this barrier and a wait queue entry. * Whenever a new tasklet reaches the barrier (barrier_wait), the counter is decremented and the tasklet * is put into the wait queue. * If the counter is reduced to 0, all the tasklets that were suspended by this barrier will be resumed and * the counter will be reinitialised to its initial value. */ #include #include #include /** * @typedef barrier_t * @brief A barrier object, as declared by BARRIER_INIT. */ typedef struct barrier_t { uint8_t wait_queue; uint8_t count; uint8_t initial_count; uint8_t lock; } barrier_t; /** * @def BARRIER_INIT * @hideinitializer * @brief Declare and initialize a barrier associated to the given name. */ /* clang-format off */ #define BARRIER_INIT(_name, _counter) \ _Static_assert((_counter < 128) && (_counter >= -127), "barrier counter must be encoded on a byte"); \ ATOMIC_BIT_INIT(__CONCAT(barrier_, _name)); \ extern barrier_t _name; \ __asm__(".section .data." __STR(_name) "\n" \ ".type " __STR( _name) ",@object\n" \ ".globl " __STR( _name) "\n" \ ".p2align 2\n" __STR(_name) ":\n" \ ".byte 0xFF\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(ATOMIC_BIT_GET(__CONCAT(barrier_,_name))) "\n" \ ".size " __STR(_name) ", 4\n" \ ".text"); /* clang-format on */ /** * @fn barrier_wait * @brief Decrements the counter associated to the barrier and suspends the invoking tasklet. * * The counter of the barrier is decremented and the invoking tasklet is suspended until * the counter associated to the barrier is reduced to 0. * * @param barrier the barrier the tasklet will be associated to. */ void barrier_wait(barrier_t *barrier); #endif /* DPUSYSCORE_BARRIER_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/bswapdi2.c ================================================ /* ===-- bswapdi2.c - Implement __bswapdi2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __bswapdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" COMPILER_RT_ABI uint64_t __bswapdi2(uint64_t u) { return ((((u)&0xff00000000000000ULL) >> 56) | (((u)&0x00ff000000000000ULL) >> 40) | (((u)&0x0000ff0000000000ULL) >> 24) | (((u)&0x000000ff00000000ULL) >> 8) | (((u)&0x00000000ff000000ULL) << 8) | (((u)&0x0000000000ff0000ULL) << 24) | (((u)&0x000000000000ff00ULL) << 40) | (((u)&0x00000000000000ffULL) << 56)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/bswapsi2.c ================================================ /* ===-- bswapsi2.c - Implement __bswapsi2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __bswapsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" COMPILER_RT_ABI uint32_t __bswapsi2(uint32_t u) { return ((((u)&0xff000000) >> 24) | (((u)&0x00ff0000) >> 8) | (((u)&0x0000ff00) << 8) | (((u)&0x000000ff) << 24)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/buddy_alloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include //for mem_alloc #include //for size_t #include //for memset #include #include #include #include #include #include #include static unsigned char __buddy_init_done = 0; static int *__buddy_blocks = 0; static void *__buddy_heap_start = 0; static unsigned int __BUDDY_SIZE_OF_HEAP__ = 0; static unsigned char __BUDDY_MAX_POWER__ = 0; static unsigned char __BUDDY_NUMBER_OF_LEVELS__ = 0; ATOMIC_BIT_INIT(__buddy_lock); #define __BUDDY_DEPTH_LEVELS__ 3 #define __BUDDY_SHIFT_ADDRESS_TO_INDEX__ 4 static inline unsigned int next_power_of_2(int x) { // in order to find the size of the block to allocate we // count the number of leading zeros to get the correct // log2(size) // if size has only one "1" bit then we keep this power of 2 // otherwise, we add 1 unsigned int power_of_2 = 31 - count_leading_zeros(x); if (count_population(x) != 1) { power_of_2++; } return power_of_2; } /* * Note 1: * each bit represents the state of a block. It can equal either 0 or 1 and can represent 4 different states of a block : * target = 1 & buddy = 0 -> free : target block is [free] and can be * allocated without the need to cut the bigger block in half target = 1 & buddy = 1 -> not * in use : neither target nor its buddy are in use and bigger blocks must be checked * * target = 0 & both successors = 1 [not in use] -> allocated : this block is completely allocated * target = 0 & one or both of the successors = 0 [allocated] -> partially allocated : block is partially allocated i.e. * at least one of the sub-blocks is [allocated] * * Note 2: * Indexes of __buddy_blocks are indeed quite bizarre, which was a mistake during the conception stage. It doesn't change much. * Indexe_in_level start from 0 from left to right, but not for the 5 least significant bits where they still start from 0 but * from right to left */ void * safe_buddy_alloc(size_t size) { if ((size == 0) || (size > __BUDDY_SIZE_OF_HEAP__)) { errno = EINVAL; return NULL; } // we replace the size by the smallest 2 to the power of X such as it is greater than or equals the size // afterwards, we take X as power_of_2 and thereby find the correct level to search for free blocks: // blocks_level = __BUDDY_MAX_POWER__ - power_of_2 // for example if we try to allocate a block of 64 bytes (64=2^6), blocks_level = __BUDDY_MAX_POWER__ - 6 unsigned int power_of_2 = next_power_of_2(size); int blocks_level = __BUDDY_MAX_POWER__ - power_of_2; // if the size is smaller than the minimal size of // block divided by 2, then we can't allocate a block // so small and we have to allocate the block of the // minimal allowed size if (blocks_level >= __BUDDY_NUMBER_OF_LEVELS__) { blocks_level = __BUDDY_NUMBER_OF_LEVELS__ - 1; } // we browse all levels until we find the smallest free block that is big enough to contain "size" bytes for (int blocks_level_current = blocks_level; blocks_level_current >= 0; --blocks_level_current) { // we initialise index_in_level as the biggest index permitted in level unsigned int index_in_level = 1 << blocks_level_current; // levels 0-4 are in the same bitfield, // level 5 consists of a single bitfield // all other levels consist of 1<<(#level - 5) // bitfields unsigned int initial_number_of_current_bitfield = 0; unsigned int loaded_case_mask; switch (blocks_level_current) { default: initial_number_of_current_bitfield = ((1 << blocks_level_current) >> 5) - 1; loaded_case_mask = 0xFFFFFFFF; break; case 0: loaded_case_mask = 0x40000000; break; case 1: loaded_case_mask = 0x30000000; break; case 2: loaded_case_mask = 0x0F000000; break; case 3: loaded_case_mask = 0x00FF0000; break; case 4: loaded_case_mask = 0x0000FFFF; break; } for (int number_of_current_bitfield = initial_number_of_current_bitfield; number_of_current_bitfield >= 0; --number_of_current_bitfield, index_in_level -= 32) { // sizes of levels in __buddy_blocks is a geometric // series and thereby we can easily calculate the // number of bitfields that precede the current level unsigned int real_index = (1 << blocks_level_current) >> 5; // we load the bitfield unsigned int *initial_loaded_case_address = (unsigned int *)(__buddy_blocks + number_of_current_bitfield + real_index); // if we are in the very first bitfield // that contains first 5 levels, then we // need to make sure that buddy_free will // ignore the bits that represent blocks // that don't belong to blocks_level_current unsigned int loaded_case = *initial_loaded_case_address & loaded_case_mask; // this formula gives the number of zeros // before the first pair of free/allocated blocks // present in the current bitfield. If it equals // 32, then no such pair is present. unsigned int lz_before_first_pair_tmp = ((loaded_case << 1) ^ loaded_case) & 0xAAAAAAAA; if (lz_before_first_pair_tmp != 0) { unsigned int lz_before_first_pair = count_leading_zeros(lz_before_first_pair_tmp); index_in_level = index_in_level - lz_before_first_pair - 1; // if we are in the very first bitfield, // then we need to take into account the special // positioning of the 5 levels of blocks // inside this bitfield if (blocks_level_current < 5) { index_in_level += 1 << blocks_level_current; } unsigned int highlight_target_bit = 1 << index_in_level; // if current level is among first 4 //(5th is unnecessary to consider) // then we need to shift the mask if (blocks_level_current < 4) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) highlight_target_bit = highlight_target_bit << (32 - (2 << blocks_level_current)); } // we have the position of a pair of // free/allocated blocks, but we might // need to shift this position by 1 // if the target's buddy is the potential // block to allocate loaded_case = loaded_case & highlight_target_bit; if (loaded_case == 0) { highlight_target_bit = highlight_target_bit >> 1; index_in_level--; } // loaded_case have been modified if the first bitfield is handled loaded_case = *initial_loaded_case_address; // we mark the target bit as allocated loaded_case -= highlight_target_bit; *initial_loaded_case_address = loaded_case; // if we have already had a free block of the necessary size, // we return its address, otherwise we jump to //__buddy_alloc_break_loop and start cutting the blocks // in half until we get a block of the required size if (blocks_level == blocks_level_current) { return __buddy_heap_start + (index_in_level << (__BUDDY_MAX_POWER__ - blocks_level)); } // we have already set the block to 0 [partially allocated] // so we descend and start with the next one blocks_level_current++; while (blocks_level_current <= blocks_level) { index_in_level = index_in_level << 1; highlight_target_bit = 1 << index_in_level; // first 5 levels are stored in the same // bitfield. We need to handle this // special case and shift the mask int blocks_level_clamped = blocks_level_current - 4; if (blocks_level_clamped < 0) { highlight_target_bit = highlight_target_bit << (32 - (2 << blocks_level_current)); } // we load the bitfield // real_index is the offset in 32-bit words from the first bitfield in __buddy_blocks unsigned int real_index = 0; blocks_level_clamped--; if (blocks_level_clamped >= 0) { real_index = 1 << blocks_level_clamped; blocks_level_clamped = index_in_level >> 5; real_index += blocks_level_clamped; } loaded_case = __buddy_blocks[real_index]; // we mark the bit as allocated __buddy_blocks[real_index] = loaded_case - highlight_target_bit; // we continue to descend blocks_level_current++; } return __buddy_heap_start + (index_in_level << (__BUDDY_MAX_POWER__ - blocks_level)); } } } // if no level contains a big enough block, we return NULL errno = ENOMEM; return NULL; } typedef struct _buddy_search_context_t { unsigned int target_level; unsigned int real_index; unsigned int highlight_target_bit; unsigned int highlight_buddy_bit; } * buddy_search_context_t; int buddy_search_for_pointer(void *pointer, buddy_search_context_t context) { // if the pointer is not aligned to 64 bits, then it is corrupted // if the pointer is outside of the heap, we can do nothing if (((((unsigned int)pointer) & 7) != 0) || (pointer < __buddy_heap_start) || (pointer > (__buddy_heap_start + __BUDDY_SIZE_OF_HEAP__ - 1))) { errno = EINVAL; return -1; } // we transform the real address into an index for __buddy_blocks // index_in_level = (pointer - START_OF_HEAP)>>__BUDDY_SHIFT_ADDRESS_TO_INDEX__; unsigned int index_in_level = (pointer - __buddy_heap_start) >> __BUDDY_SHIFT_ADDRESS_TO_INDEX__; // we start to search for the pointer from the lowest level unsigned int target_level = __BUDDY_NUMBER_OF_LEVELS__ - 1; while (true) { // knowing the index_in_level we can calculate // highlight_target_bit and highlight_buddy_bit unsigned int highlight_target_bit = 1 << index_in_level; unsigned int highlight_buddy_bit; if ((count_leading_zeros(highlight_target_bit) & 1) == 0) { highlight_buddy_bit = highlight_target_bit >> 1; } else { highlight_buddy_bit = highlight_target_bit << 1; } // first 5 levels are stored in the // same bitfield. We need to handle // this special case and shift // the masks int target_level_clamped = target_level - 4; if (target_level_clamped < 0) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) unsigned int offset = 32 - (2 << target_level); highlight_buddy_bit = highlight_buddy_bit << offset; highlight_target_bit = highlight_target_bit << offset; } // we load a bitfield corresponding to the index // in __buddy_blocks // real_index is the offset in 32-bit words from the first bitfield in __buddy_blocks unsigned int real_index = 0; target_level_clamped--; if (target_level_clamped >= 0) { real_index = (1 << target_level_clamped); target_level_clamped = index_in_level >> 5; real_index = real_index + target_level_clamped; } unsigned int loaded_case = __buddy_blocks[real_index]; // We search for an allocated block // if we are on the highest level, we quit. if (((loaded_case & highlight_target_bit) == 0) || (target_level <= 0)) { context->target_level = target_level; context->real_index = real_index; context->highlight_target_bit = highlight_target_bit; context->highlight_buddy_bit = highlight_buddy_bit; return index_in_level; } // Condition required to avoid unwanted release if ((loaded_case & highlight_buddy_bit) == 0) { errno = EINVAL; return -1; } // we rise to the higher level index_in_level = index_in_level >> 1; target_level--; } } static void buddy_free_fusion_of_blocks(unsigned int index, buddy_search_context_t context) { unsigned int real_index = context->real_index; unsigned int current_level_freeing = context->target_level; unsigned int highlight_target_bit = context->highlight_target_bit; unsigned int highlight_buddy_bit = context->highlight_buddy_bit; unsigned int loaded_case = __buddy_blocks[real_index]; // if we are at the highest level, there is nothing to fuse while (current_level_freeing > 0) { // fusion occurs only when both blocks are free if (((loaded_case & highlight_target_bit) == 0) | ((loaded_case & highlight_buddy_bit) == 0)) { return; } // index of predecessor = index of successor >> 1 index = index >> 1; // we rise to the higher level current_level_freeing--; // knowing the index_in_level we can calculate // highlight_target_bit and highlight_buddy_bit highlight_target_bit = 1 << index; if ((count_leading_zeros(highlight_target_bit) & 1) == 0) { highlight_buddy_bit = highlight_target_bit >> 1; } else { highlight_buddy_bit = highlight_target_bit << 1; } // first 5 levels are stored in the same bitfield. // We need to handle this special case and shift // the masks int target_level_clamped = current_level_freeing - 4; if (target_level_clamped < 0) { // we want to find the value of the offset to shift the mask for target and its buddy // offset = 32 - 2^(current_lvl+1) unsigned int offset = 32 - (2 << current_level_freeing); highlight_buddy_bit = highlight_buddy_bit << offset; highlight_target_bit = highlight_target_bit << offset; } // we load a bitfield corresponding // to the index in __buddy_blocks // // As both sub-blocks were freed, their "father" // must be marked as free. real_index = 0; target_level_clamped--; if (target_level_clamped >= 0) { real_index = (1 << target_level_clamped); target_level_clamped = index >> 5; real_index = real_index + target_level_clamped; } loaded_case = __buddy_blocks[real_index] | highlight_target_bit; __buddy_blocks[real_index] = loaded_case; } } void safe_buddy_free(void *pointer) { struct _buddy_search_context_t context; int index = buddy_search_for_pointer(pointer, &context); if (index != -1) { __buddy_blocks[context.real_index] |= context.highlight_target_bit; buddy_free_fusion_of_blocks(index, &context); } } // noinline, because part of grind tracked functions void __noinline * buddy_alloc(size_t size) { ATOMIC_BIT_ACQUIRE(__buddy_lock); void *result = safe_buddy_alloc(size); ATOMIC_BIT_RELEASE(__buddy_lock); return result; } // noinline, because part of grind tracked functions void __noinline buddy_free(void *pointer) { ATOMIC_BIT_ACQUIRE(__buddy_lock); safe_buddy_free(pointer); ATOMIC_BIT_RELEASE(__buddy_lock); } /*if the size of the smallest block needs to be changed, then only 2 things need to change : * __BUDDY_DEPTH_LEVELS__ here in buddy_init.c * __BUDDY_SHIFT_ADDRESS_TO_INDEX__ in buddy_defs.s * * When the minimal size of a block needs to be 32 bytes, then these two constants must equal 4 and 5 correspondingly * If minimal size needs to be 16 bytes, then these two constants must equal 3 and 4 correspondingly * If minimal size needs to be 8 bytes, then these two constants must equal 2 and 3 correspondingly * * Also, certain tests (Global, Reset, LevelByLevel) should also be changed. */ // TODO: Right now the size must be of power of 2 : 2048, 4096, 8192 and it won't work with other sizes. // TODO: There is no point in accepting other sizes, as the whole idea of having buddy allocation is based on it. // TODO: Right now the possibility of failure of mem_alloc is not taken into account of. // noinline, because part of grind tracked functions void __noinline buddy_init(size_t size_of_heap) { if (__buddy_init_done == 0) { ATOMIC_BIT_RELEASE(__buddy_lock); __BUDDY_SIZE_OF_HEAP__ = size_of_heap; unsigned int power_of_2 = count_leading_zeros(size_of_heap); __BUDDY_MAX_POWER__ = (31 - power_of_2); __BUDDY_NUMBER_OF_LEVELS__ = __BUDDY_MAX_POWER__ - __BUDDY_DEPTH_LEVELS__; unsigned int blocks_in_buddy_blocks = (1 << (__BUDDY_NUMBER_OF_LEVELS__ - 5)) << 2; __buddy_blocks = mem_alloc(size_of_heap + blocks_in_buddy_blocks); __buddy_heap_start = __buddy_blocks + (blocks_in_buddy_blocks >> 2); __buddy_blocks[0] = 0x7fffffff; // all bits except for the very first one must be set to 1 memset(&__buddy_blocks[1], 0xff, blocks_in_buddy_blocks - 4); // in order to initialize the __buddy_blocks structure __buddy_init_done = 1; } } // noinline, because part of grind tracked functions void __noinline buddy_reset() { ATOMIC_BIT_ACQUIRE(__buddy_lock); __buddy_blocks[0] = 0x7fffffff; // all bits except for the very first one must be set to 1 memset(&__buddy_blocks[1], 0xff, ((1 << (__BUDDY_NUMBER_OF_LEVELS__ - 5)) << 2) - 4); // in order to initialize the __buddy_blocks structure ATOMIC_BIT_RELEASE(__buddy_lock); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/buddy_alloc.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_BUDDY_ALLOC_H #define DPUSYSCORE_BUDDY_ALLOC_H /** * @file buddy_alloc.h * @brief Dynamic memory allocation and freeing. * * This library allows to create unique memory space in the heap to allocate and free * blocks of data. * * The memory space is initialized with buddy_init, which must be invoked only once during * the program's lifecycle. * * Functions can then dynamically get and free buffers, using buddy_alloc and buddy_free * respectively. * * In this implementation, the allocatable buffer size is chosen during the first call to buddy_init. * Tested sizes : 2048, 4096, 8192, 16384 and 32768 bytes * The allocated buffers are properly aligned on DMA transfer constraints, so that they can be * used as is in MRAM/WRAM transfer operations. */ /* * @internal The algorithm used in this implementation is Buddy memory allocation. * * A particularity of this implementation is that no headers are created and thereby * the memory consumption of the heap is reduced. The drawback is a slight slow-down * in speed of memory freeing. * * Warning : * Due to the particularities of the implementation (lack of headers), buddy_free * will always try to find a pointer to free. If the pointer given in the parameter * is not currently allocated by buddy_alloc or buddy_realloc, buddy_free * will do nothing. * */ #include /** * @fn buddy_init * @brief Allocates size_of_heap bytes for a heap that buddy_alloc can access to. * * Reserves memory space in the heap used to perform dynamic allocation and release of buffers. * * @param size_of_heap the size of heap in bytes that buddy_alloc can access to */ void buddy_init(size_t size_of_heap); /** * @fn buddy_reset * @brief Resets the heap. * * Quickly frees all pointers allocated by buddy_alloc or buddy_realloc. * Warning : currently buddy_reset() doesn't reset the size of the allocated heap. */ void buddy_reset(void); /** * @fn buddy_alloc * @brief Allocates a buffer of the given size in the heap, in a runtime-safe way. * * The allocated buffer is aligned on 64 bits, in order to ensure compatibility * with the maximum buffer alignment constraint. As a consequence, a buffer * allocated with this function is also compatible with data transfers to/from MRAM. * * Due to the idea of the buddy algorithm (to decrease external fragmentation), * the allocated blocks will be of size equal to a power of 2. In other words, * if the user allocates 33 bytes, 64 bytes will be allocated and when 2049 bytes * are requested, 4096 will be allocated. The user might want to take this into * account if she/he wishes to minimise the memory consumption. * * The minimal size of the allocated block is 16 bytes, but can easily be changed in * future implementations, so buddy_alloc is mostly adapted to allocating medium and * big structures, such as arrays containing more than 8 bytes (in order to make sure * that not too much memory space is wasted), binary trees or linked lists. * * If the size passed in parameter is less or equal to 0 or greater than the size of heap, * errno will be set to EINVAL and buddy_alloc will do nothing. * If buddy_alloc fails to find enough free memory space to allocate, errno will be * set to ENOMEM. * * @param size the allocated buffer's size, in bytes * @return A pointer to the allocated buffer if one was available, NULL otherwise. */ void * buddy_alloc(size_t size); /** * @fn buddy_free * @brief Frees a specified pointer, in a runtime-safe way. * * Warning : * Due to the particularities of the implementation (lack of headers), buddy_free * will always try to find a pointer to free and will see a pointer to the beginning of the * block in the same way as the pointer to anywhere inside the block. For example, if we have * allocated an int array[10], buddy_free will treat &array[0] the same way as &array[1] * or as the address of any other element inside this array and will free the whole block. * * If the pointer given in the parameter is not currently allocated by buddy_alloc or * buddy_realloc, buddy_free will do nothing. * * This function frees the memory space pointed to by pointer, which * must have been returned by a previous call to buddy_alloc or buddy_realloc * If it wasn't or if buddy_free has already been called for this pointer before, * then buddy_free will do nothing. If pointer is NULL, no operation is performed. * If the pointer passed as a parameter is not aligned to 64 bits or if it is outside * of the allocated heap errno will be set to EINVAL. * If buddy_free detects the attempt to free a non-allocated pointer, it will equally * set errno to EINVAL. * * @param pointer the pointer to the block to free */ void buddy_free(void *pointer); /** * @fn buddy_realloc * @brief Changes the size of the memory block pointed to by ptr to size bytes in a runtime-safe way. * * The contents will be unchanged in the range from the start of the region up to the minimum of the old and new sizes. * If the new size is larger than the old size, the added memory will not be initialized. * If ptr is NULL, then the call is equivalent to buddy_alloc(size) for all values of size. * If size is equal to zero, and ptr is not NULL, then the call is equivalent to * buddy_free(ptr) and the return value will be equal to the pointer passed as the parameter. Unless ptr * is NULL, it should have been returned by an earlier call to buddy_alloc() or buddy_realloc(). If it * wasn't, then buddy_realloc() will try to find this pointer among the allocated ones, but undefined behavior might * occur. * * If new size is smaller than the old size, then the remaining memory will potentially be released (depends * on the size of block). * * buddy_realloc() internally calls buddy_alloc and buddy_free and thereby will set errno * to ENOMEM or EINVAL on failure. * * @param ptr original pointer * @param size the new allocated buffer's size, in bytes * @return A new (or the same) pointer to the allocated buffer if one was available, NULL otherwise. */ void * buddy_realloc(void *ptr, size_t size); #endif /* DPUSYSCORE_BUDDY_ALLOC_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/buddy_realloc.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ // todo integrate in buddy_alloc.c, when we have reduced the buddy_alloc object file size #include #include #include #include //for memcpy #include #include #include ATOMIC_BIT_EXTERN(__buddy_lock); typedef struct _buddy_search_context_t { unsigned int target_level; unsigned int real_index; unsigned int highlight_target_bit; unsigned int highlight_buddy_bit; } * buddy_search_context_t; extern void * safe_buddy_alloc(size_t size); extern void safe_buddy_free(void *ptr); extern int buddy_search_for_pointer(void *ptr, buddy_search_context_t context); static int buddy_sizeofblock(void *pointer) { // We get the pointer (address) as the parameter and look for any allocated block that starts at this address. // If it is allocated, it will be found and its size will be returned. // If it is currently non allocated, buddy_sizeofblock will do nothing. struct _buddy_search_context_t dummy; int index = buddy_search_for_pointer(pointer, &dummy); if (index == -1) { return -1; } return 1 << (12 - index); } // noinline, because part of grind tracked functions void *__noinline buddy_realloc(void *ptr, size_t size) { ATOMIC_BIT_ACQUIRE(__buddy_lock); void *result = ptr; if (ptr == NULL) { // if ptr == NULL, then buddy_realloc must behave as buddy_alloc result = safe_buddy_alloc(size); ATOMIC_BIT_RELEASE(__buddy_lock); return result; // } if (size == 0) { // if size == 0 and ptr != NULL, then buddy_realloc behaves as buddy_free safe_buddy_free(ptr); // ATOMIC_BIT_RELEASE(__buddy_lock); // return ptr; // } size_t size_block = buddy_sizeofblock(ptr); if (size_block == ((size_t)-1)) { // size_block is set to -1 if ptr was not found among ATOMIC_BIT_RELEASE(__buddy_lock); // allocated pointers and that there is nothing to do return NULL; } if (size <= (size_block >> 1)) { // if newly allocated block is smaller than the currently allocated block size_block = size; // we will only copy "size" bytes } else if (size <= size_block) { // if newly allocated block is of the same size as the currently allocated block ATOMIC_BIT_RELEASE(__buddy_lock); // then there is no reason to do anything return ptr; } safe_buddy_free(ptr); // newly allocated block is either bigger or smaller than the currently allocated result = safe_buddy_alloc(size); // block and we need to call buddy_alloc to be sure that external fragmentation memcpy(result, ptr, size_block); // is avoided. ATOMIC_BIT_RELEASE(__buddy_lock); return result; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/built_ins.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef BUILT_INS_H #define BUILT_INS_H /** * @file built_ins.h * @brief Provides access to the built-in functions * * Automatically generated by the DPU assembler */ #define __builtin_nor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rrif(dc, ra, imm, false_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_u_rrr(dc, ra, rb) \ __asm__("nor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rric(dc, ra, imm, log_set_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rrif(dc, ra, imm, false_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_u_rrr(dc, ra, rb) \ __asm__("hash.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rri(rc, ra, shift) __asm__("lsr %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_zri(zero, ra, shift) __asm__("lsr %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_rrr(rc, ra, rb) \ __asm__("lsr %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_zrr(zero, ra, rb) __asm__("lsr %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_boot_rici(ra, imm, boot_cc, pc) __asm__("boot %[ra_r32], " imm ", " boot_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sb_erir(endian, ra, off, rb) \ __asm__("sb " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sb_erii(endian, ra, off, imm) __asm__("sb " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sb_esir(endian, sa, off, rb) \ __asm__("sb " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sb_esii(endian, sa, off, imm) __asm__("sb " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lsl_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rri(dc, ra, shift) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_s_rrr(dc, ra, rb) \ __asm__("lsl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rri(rc, ra, shift) __asm__("lsl %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_zri(zero, ra, shift) __asm__("lsl %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_rrr(rc, ra, rb) \ __asm__("lsl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_zrr(zero, ra, rb) __asm__("lsl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lhu_erri(endian, rc, ra, off) \ __asm__("lhu " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lhu_ersi(endian, rc, sa, off) \ __asm__("lhu " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_sw_erir(endian, ra, off, rb) \ __asm__("sw " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sw_erii(endian, ra, off, imm) __asm__("sw " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sw_esir(endian, sa, off, rb) \ __asm__("sw " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sw_esii(endian, sa, off, imm) __asm__("sw " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_asr_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rric(dc, ra, shift, log_set_cc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rri(dc, ra, shift) \ __asm__("asr.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_s_rrr(dc, ra, rb) \ __asm__("asr.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rri(dc, ra, shift) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_s_rrr(dc, ra, rb) \ __asm__("lsr1x.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_rrr(rc, ra, rb) \ __asm__("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_zrr(zero, ra, rb) \ __asm__("mul_uh_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rric(dc, ra, shift, log_set_cc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rri(dc, ra, shift) \ __asm__("ror.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_u_rrr(dc, ra, rb) \ __asm__("ror.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_u_rrr(dc, ra, rb) \ __asm__("mul_ul_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rri(rc, ra, imm) __asm__("addc %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zri(zero, rb, imm) __asm__("addc %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_addc_rrici(rc, ra, imm, add_nz_cc, pc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zrici(zero, ra, imm, add_nz_cc, pc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rric(rc, ra, imm, log_set_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zric(zero, ra, imm, log_set_cc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rrif(rc, ra, imm, false_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_addc_zrif(zero, ra, imm, false_cc) \ __asm__("addc %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_addc_rrrci(rc, ra, rb, add_nz_cc, pc) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_zrrci(zero, ra, rb, add_nz_cc, pc) \ __asm__("addc %[zero], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rrrc(rc, ra, rb, log_set_cc) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_zrrc(zero, ra, rb, log_set_cc) \ __asm__("addc %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_rrr(rc, ra, rb) \ __asm__("addc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_addc_zrr(zero, ra, rb) __asm__("addc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_u_rrri(dc, rb, ra, shift) \ __asm__("lsl_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_time_cfg_u_rrci(dc, rb, true_cc, pc) \ __asm__("time_cfg.u %[dc_wr64], %[rb_wr32], " true_cc ", " pc "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_u_rr(dc, rb) __asm__("time_cfg.u %[dc_wr64], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_rrr(rc, ra, rb) \ __asm__("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_ul_zrr(zero, ra, rb) \ __asm__("mul_ul_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_time_s_rci(dc, true_cc, pc) __asm__("time.s %[dc_wr64], " true_cc ", " pc "" : [dc_wr64] "=r"(dc)::) #define __builtin_time_s_r(dc) __asm__("time.s %[dc_wr64]" : [dc_wr64] "=r"(dc)::) #define __builtin_call_rri(rc, ra, off) __asm__("call %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_call_zri(zero, ra, off) __asm__("call %[zero], %[ra_r32], " off "" ::[ra_r32] "r"(ra) :) #define __builtin_call_rrr(rc, ra, rb) \ __asm__("call %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_call_zrr(zero, ra, rb) __asm__("call %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1 %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl1 %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rri(rc, ra, shift) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_zri(zero, ra, shift) __asm__("lsl1 %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_rrr(rc, ra, rb) \ __asm__("lsl1 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_zrr(zero, ra, rb) __asm__("lsl1 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rric(dc, ra, imm, log_set_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rrif(dc, ra, imm, false_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_u_rrr(dc, ra, rb) \ __asm__("orn.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rric(dc, ra, shift, log_set_cc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rri(dc, ra, shift) \ __asm__("rol.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_u_rrr(dc, ra, rb) \ __asm__("rol.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_stop_ci(boot_cc, pc) __asm__("stop " boot_cc ", " pc "" :::) #define __builtin_ldmai_rri(ra, rb, immDma) \ __asm__("ldmai %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rri(dc, ra, shift) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_s_rrr(dc, ra, rb) \ __asm__("lsr.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_u_rrri(dc, rb, ra, shift) \ __asm__("lsr_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_time_cfg_rrci(rc, rb, true_cc, pc) \ __asm__("time_cfg %[rc_wr32], %[rb_wr32], " true_cc ", " pc "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_zrci(zero, rb, true_cc, pc) \ __asm__("time_cfg %[zero], %[rb_wr32], " true_cc ", " pc "" ::[rb_wr32] "r"(rb) :) #define __builtin_time_cfg_rr(rc, rb) __asm__("time_cfg %[rc_wr32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_zr(zero, rb) __asm__("time_cfg %[zero], %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_or_rri(rc, ra, imm) __asm__("or %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zri(zero, rb, imm) __asm__("or %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_or_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("or %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rric(rc, ra, imm, log_set_cc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zric(zero, ra, imm, log_set_cc) \ __asm__("or %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rrif(rc, ra, imm, false_cc) \ __asm__("or %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_or_zrif(zero, ra, imm, false_cc) __asm__("or %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_or_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("or %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_rrrc(rc, ra, rb, log_set_cc) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_zrrc(zero, ra, rb, log_set_cc) \ __asm__("or %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_rrr(rc, ra, rb) \ __asm__("or %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_zrr(zero, ra, rb) __asm__("or %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_rrr(rc, ra, rb) \ __asm__("mul_sl_sl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_zrr(zero, ra, rb) \ __asm__("mul_sl_sl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cao_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cao.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_u_rrc(dc, ra, log_set_cc) \ __asm__("cao.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_u_rr(dc, ra) __asm__("cao.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rric(rc, ra, shift, log_set_cc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zric(zero, ra, shift, log_set_cc) \ __asm__("lsrx %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rri(rc, ra, shift) \ __asm__("lsrx %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_zri(zero, ra, shift) __asm__("lsrx %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsrx_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_rrr(rc, ra, rb) \ __asm__("lsrx %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_zrr(zero, ra, rb) __asm__("lsrx %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cls_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cls.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_u_rrc(dc, ra, log_set_cc) \ __asm__("cls.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_u_rr(dc, ra) __asm__("cls.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_mul_sh_sl_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_rrr(rc, ra, rb) \ __asm__("mul_sh_sl %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_zrr(zero, ra, rb) \ __asm__("mul_sh_sl %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sd_erir(endian, ra, off, db) \ __asm__("sd " endian ", %[ra_r32], " off ", %[db_wr64]" ::[ra_r32] "r"(ra), [db_wr64] "r"(db) :) #define __builtin_sd_erii(endian, ra, off, imm) __asm__("sd " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sd_esir(endian, sa, off, db) \ __asm__("sd " endian ", %[sa_r32], " off ", %[db_wr64]" ::[sa_r32] "r"(sa), [db_wr64] "r"(db) :) #define __builtin_sd_esii(endian, sa, off, imm) __asm__("sd " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lsrx_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rri(dc, ra, shift) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_s_rrr(dc, ra, rb) \ __asm__("lsrx.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_add_rrri(rc, rb, ra, shift) \ __asm__("lsl_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_add_zrri(zero, rb, ra, shift) \ __asm__("lsl_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rri(dc, ra, shift) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_s_rrr(dc, ra, rb) \ __asm__("lsr1.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sdma_rri(ra, rb, immDma) \ __asm__("sdma %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lhs_s_erri(endian, dc, ra, off) \ __asm__("lhs.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rri(dc, ra, shift) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_s_rrr(dc, ra, rb) \ __asm__("lslx.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_s_rrr(dc, ra, rb) \ __asm__("cmpb4.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr1x %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rri(rc, ra, shift) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_zri(zero, ra, shift) __asm__("lsr1x %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_rrr(rc, ra, rb) \ __asm__("lsr1x %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1x_zrr(zero, ra, rb) __asm__("lsr1x %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_ul_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_ul_u_rrr(dc, ra, rb) \ __asm__("mul_uh_ul.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbu_erri(endian, rc, ra, off) \ __asm__("lbu " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lbu_ersi(endian, rc, sa, off) \ __asm__("lbu " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_time_u_rci(dc, true_cc, pc) __asm__("time.u %[dc_wr64], " true_cc ", " pc "" : [dc_wr64] "=r"(dc)::) #define __builtin_time_u_r(dc) __asm__("time.u %[dc_wr64]" : [dc_wr64] "=r"(dc)::) #define __builtin_subc_s_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rirc(dc, imm, ra, sub_set_cc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rirf(dc, imm, ra, false_cc) \ __asm__("subc.s %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrif(dc, ra, imm, false_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_s_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_s_rrr(dc, ra, rb) \ __asm__("subc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clo.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_s_rrc(dc, ra, log_set_cc) \ __asm__("clo.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_s_rr(dc, ra) __asm__("clo.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrif(dc, ra, imm, false_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_s_rrr(dc, ra, rb) \ __asm__("xor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_rrr(rc, ra, rb) \ __asm__("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_zrr(zero, ra, rb) \ __asm__("mul_ul_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_rrr(rc, ra, rb) \ __asm__("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_zrr(zero, ra, rb) \ __asm__("mul_uh_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_ul_uh_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_ul_uh_u_rrr(dc, ra, rb) \ __asm__("mul_ul_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_s_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_s_rrr(dc, ra, rb) \ __asm__("rsub.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrrc(rc, ra, rb, log_set_cc) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_zrrc(zero, ra, rb, log_set_cc) \ __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_rrr(rc, ra, rb) \ __asm__("cmpb4 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_zrr(zero, ra, rb) __asm__("cmpb4 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rric(rc, ra, imm, log_set_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zric(zero, ra, imm, log_set_cc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rrif(rc, ra, imm, false_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_hash_zrif(zero, ra, imm, false_cc) \ __asm__("hash %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_hash_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("hash %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrrc(rc, ra, rb, log_set_cc) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_zrrc(zero, ra, rb, log_set_cc) \ __asm__("hash %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_rrr(rc, ra, rb) \ __asm__("hash %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_hash_zrr(zero, ra, rb) __asm__("hash %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rir(rc, imm, ra) __asm__("sub %[rc_wr32], " imm ", %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zir(zero, imm, rb) __asm__("sub %[zero], " imm ", %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_sub_rirci(rc, imm, ra, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirci(zero, imm, ra, sub_nz_cc, pc) \ __asm__("sub %[zero], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rirc(rc, imm, ra, sub_set_cc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirc(zero, imm, ra, sub_set_cc) \ __asm__("sub %[zero], " imm ", %[ra_r32], " sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rirf(rc, imm, ra, false_cc) \ __asm__("sub %[rc_wr32], " imm ", %[ra_r32], " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zirf(zero, imm, ra, false_cc) __asm__("sub %[zero], " imm ", %[ra_r32], " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rrici(rc, ra, imm, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zrici(zero, ra, imm, sub_nz_cc, pc) \ __asm__("sub %[zero], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rric(rc, ra, imm, ext_sub_set_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " ext_sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zric(zero, ra, imm, ext_sub_set_cc) \ __asm__("sub %[zero], %[ra_r32], " imm ", " ext_sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_rrif(rc, ra, imm, false_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sub_zrif(zero, ra, imm, false_cc) __asm__("sub %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sub_ssi(sc, sa, imm) __asm__("sub %[sc_wr32], %[sa_r32], " imm "" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa) :) #define __builtin_sub_sss(sc, sa, sb) \ __asm__("sub %[sc_wr32], %[sa_r32], %[sb_wr32]" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa), [sb_wr32] "r"(sb) :) #define __builtin_sub_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("sub %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rrrc(rc, ra, rb, ext_sub_set_cc) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_zrrc(zero, ra, rb, ext_sub_set_cc) \ __asm__("sub %[zero], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_rrr(rc, ra, rb) \ __asm__("sub %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sub_zrr(zero, ra, rb) __asm__("sub %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsb_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extsb %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extsb %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsb_rrc(rc, ra, log_set_cc) \ __asm__("extsb %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zrc(zero, ra, log_set_cc) __asm__("extsb %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsb_rr(rc, ra) __asm__("extsb %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_zr(zero, ra) __asm__("extsb %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_andn_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rric(dc, ra, imm, log_set_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rrif(dc, ra, imm, false_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_s_rrr(dc, ra, rb) \ __asm__("andn.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sl_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sl_s_rrr(dc, ra, rb) \ __asm__("mul_sl_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_movd_rrci(dc, db, true_false_cc, pc) \ __asm__("movd %[dc_wr64], %[db_wr64], " true_false_cc ", " pc "" : [dc_wr64] "=r"(dc) : [db_wr64] "r"(db) :) #define __builtin_lsl1x_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rric(rc, ra, shift, log_set_cc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zric(zero, ra, shift, log_set_cc) \ __asm__("lsl1x %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rri(rc, ra, shift) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_zri(zero, ra, shift) __asm__("lsl1x %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsl1x_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_rrr(rc, ra, rb) \ __asm__("lsl1x %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_zrr(zero, ra, rb) __asm__("lsl1x %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rri(dc, ra, shift) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr_u_rrr(dc, ra, rb) \ __asm__("lsr.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_s_rrr(dc, ra, rb) \ __asm__("mul_sl_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_s_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_s_rrr(dc, ra, rb) \ __asm__("rsubc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_s_rrri(dc, rb, ra, shift) \ __asm__("lsl_sub.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_sats_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("sats.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_s_rrc(dc, ra, log_set_cc) \ __asm__("sats.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_s_rr(dc, ra) __asm__("sats.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirc(dc, imm, ra, sub_set_cc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rirf(dc, imm, ra, false_cc) \ __asm__("sub.s %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrif(dc, ra, imm, false_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_s_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_s_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_s_rrr(dc, ra, rb) \ __asm__("sub.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rri(rc, ra, imm) __asm__("and %[rc_wr32], %[ra_wr32], " imm "" : [rc_wr32] "=r"(rc) : [ra_wr32] "r"(ra) :) #define __builtin_and_zri(zero, rb, imm) __asm__("and %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_and_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("and %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rric(rc, ra, imm, log_set_cc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zric(zero, ra, imm, log_set_cc) \ __asm__("and %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rrif(rc, ra, imm, false_cc) \ __asm__("and %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_and_zrif(zero, ra, imm, false_cc) __asm__("and %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_and_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("and %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rrrc(rc, ra, rb, log_set_cc) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_zrrc(zero, ra, rb, log_set_cc) \ __asm__("and %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_rrr(rc, ra, rb) \ __asm__("and %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_zrr(zero, ra, rb) __asm__("and %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cls_rrci(rc, ra, count_nz_cc, pc) \ __asm__("cls %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zrci(zero, ra, count_nz_cc, pc) \ __asm__("cls %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_cls_rrc(rc, ra, log_set_cc) \ __asm__("cls %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zrc(zero, ra, log_set_cc) __asm__("cls %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_cls_rr(rc, ra) __asm__("cls %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cls_zr(zero, ra) __asm__("cls %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rsub_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("rsub %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_rrrc(rc, ra, rb, sub_set_cc) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_zrrc(zero, ra, rb, sub_set_cc) \ __asm__("rsub %[zero], %[ra_r32], %[rb_wr32], " sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_rrr(rc, ra, rb) \ __asm__("rsub %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsub_zrr(zero, ra, rb) __asm__("rsub %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_div_step_rrrici(dc, ra, db, shift, div_cc, pc) \ __asm__("div_step %[dc_wr64], %[ra_r32], %[db_wr64], " shift ", " div_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [db_wr64] "r"(db) \ :) #define __builtin_rol_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rric(rc, ra, shift, log_set_cc) \ __asm__("rol %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zric(zero, ra, shift, log_set_cc) \ __asm__("rol %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rri(rc, ra, shift) __asm__("rol %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_rol_zri(zero, ra, shift) __asm__("rol %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_rol_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("rol %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_rrrc(rc, ra, rb, log_set_cc) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_zrrc(zero, ra, rb, log_set_cc) \ __asm__("rol %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_rrr(rc, ra, rb) \ __asm__("rol %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_zrr(zero, ra, rb) __asm__("rol %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rri(dc, ra, shift) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_s_rrr(dc, ra, rb) \ __asm__("lsl1.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_swapd_rrci(dc, db, true_false_cc, pc) \ __asm__("swapd %[dc_wr64], %[db_wr64], " true_false_cc ", " pc "" : [dc_wr64] "=r"(dc) : [db_wr64] "r"(db) :) #define __builtin_add_s_rri(dc, rb, imm) \ __asm__("add.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_add_s_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rric(dc, ra, imm, log_set_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rrif(dc, ra, imm, false_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_s_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_s_rrr(dc, ra, rb) \ __asm__("add.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rric(rc, ra, imm, log_set_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zric(zero, ra, imm, log_set_cc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rrif(rc, ra, imm, false_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nand_zrif(zero, ra, imm, false_cc) \ __asm__("nand %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nand_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nand %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nand %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_rrr(rc, ra, rb) \ __asm__("nand %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_zrr(zero, ra, rb) __asm__("nand %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbs_s_erri(endian, dc, ra, off) \ __asm__("lbs.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rri(dc, ra, shift) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl_u_rrr(dc, ra, rb) \ __asm__("lsl.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_s_erri(endian, dc, ra, off) \ __asm__("lw.s " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sb_id_erii(endian, ra, off, imm) __asm__("sb_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_and_s_rki(dc, ra, imm) __asm__("and.s %[dc_wr64], %[ra_r32], " imm "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rri(dc, rb, imm) \ __asm__("and.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_and_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rric(dc, ra, imm, log_set_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rrif(dc, ra, imm, false_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_s_rrr(dc, ra, rb) \ __asm__("and.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nop_() __asm__("nop " :::) #define __builtin_sd_id_erii(endian, ra, off, imm) __asm__("sd_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sh_id_erii(endian, ra, off, imm) __asm__("sh_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rri(dc, ra, shift) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1x_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1x_u_rrr(dc, ra, rb) \ __asm__("lsr1x.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsh_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extsh %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extsh %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsh_rrc(rc, ra, log_set_cc) \ __asm__("extsh %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zrc(zero, ra, log_set_cc) __asm__("extsh %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extsh_rr(rc, ra) __asm__("extsh %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_zr(zero, ra) __asm__("extsh %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rol_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_s_rrri(dc, rb, ra, shift) \ __asm__("rol_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_acquire_rici(ra, imm, acquire_cc, pc) \ __asm__("acquire %[ra_r32], " imm ", " acquire_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rri(rc, ra, imm) __asm__("xor %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zri(zero, rb, imm) __asm__("xor %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_xor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("xor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rric(rc, ra, imm, log_set_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zric(zero, ra, imm, log_set_cc) \ __asm__("xor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rrif(rc, ra, imm, false_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_xor_zrif(zero, ra, imm, false_cc) __asm__("xor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_xor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("xor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("xor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_rrr(rc, ra, rb) \ __asm__("xor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_zrr(zero, ra, rb) __asm__("xor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsrx_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rri(dc, ra, shift) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsrx_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsrx_u_rrr(dc, ra, rb) \ __asm__("lsrx.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rric(rc, ra, shift, log_set_cc) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zric(zero, ra, shift, log_set_cc) \ __asm__("lslx %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rri(rc, ra, shift) \ __asm__("lslx %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_zri(zero, ra, shift) __asm__("lslx %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lslx_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lslx %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lslx %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_rrr(rc, ra, rb) \ __asm__("lslx %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_zrr(zero, ra, rb) __asm__("lslx %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rric(dc, ra, shift, log_set_cc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rri(dc, ra, shift) \ __asm__("asr.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_asr_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_u_rrr(dc, ra, rb) \ __asm__("asr.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rrif(dc, ra, imm, false_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_s_rrr(dc, ra, rb) \ __asm__("nor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_rrr(rc, ra, rb) \ __asm__("mul_sl_sh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_sh_zrr(zero, ra, rb) \ __asm__("mul_sl_sh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_u_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rirc(dc, imm, ra, sub_set_cc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rirf(dc, imm, ra, false_cc) \ __asm__("subc.u %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrif(dc, ra, imm, false_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_subc_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_u_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_u_rrr(dc, ra, rb) \ __asm__("subc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rric(rc, ra, imm, log_set_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zric(zero, ra, imm, log_set_cc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rrif(rc, ra, imm, false_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_zrif(zero, ra, imm, false_cc) \ __asm__("nxor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nxor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nxor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nxor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_rrr(rc, ra, rb) \ __asm__("nxor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_zrr(zero, ra, rb) __asm__("nxor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_xor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rrif(dc, ra, imm, false_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_xor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_xor_u_rrr(dc, ra, rb) \ __asm__("xor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clo.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_u_rrc(dc, ra, log_set_cc) \ __asm__("clo.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clo_u_rr(dc, ra) __asm__("clo.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rric(dc, ra, imm, log_set_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrif(dc, ra, imm, false_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_s_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_s_rrr(dc, ra, rb) \ __asm__("addc.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extsh_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extsh.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_s_rrc(dc, ra, log_set_cc) \ __asm__("extsh.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsh_s_rr(dc, ra) __asm__("extsh.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrif(dc, ra, imm, false_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_s_rrr(dc, ra, rb) \ __asm__("nxor.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_cmpb4_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_cmpb4_u_rrr(dc, ra, rb) \ __asm__("cmpb4.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1x_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rri(dc, ra, shift) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_s_rrr(dc, ra, rb) \ __asm__("lsl1x.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_sub_rrri(rc, rb, ra, shift) \ __asm__("lsl_sub %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl_sub_zrri(zero, rb, ra, shift) \ __asm__("lsl_sub %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_ror_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rric(rc, ra, shift, log_set_cc) \ __asm__("ror %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zric(zero, ra, shift, log_set_cc) \ __asm__("ror %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rri(rc, ra, shift) __asm__("ror %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_ror_zri(zero, ra, shift) __asm__("ror %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_ror_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("ror %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_rrrc(rc, ra, rb, log_set_cc) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_zrrc(zero, ra, rb, log_set_cc) \ __asm__("ror %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_rrr(rc, ra, rb) \ __asm__("ror %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ror_zrr(zero, ra, rb) __asm__("ror %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_fault_i(imm) __asm__("fault " imm "" :::) #define __builtin_clz_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clz.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_s_rrc(dc, ra, log_set_cc) \ __asm__("clz.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_s_rr(dc, ra) __asm__("clz.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirci(dc, imm, ra, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirc(dc, imm, ra, sub_set_cc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rirf(dc, imm, ra, false_cc) \ __asm__("sub.u %[dc_wr64], " imm ", %[ra_r32], " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrici(dc, ra, imm, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rric(dc, ra, imm, ext_sub_set_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " ext_sub_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrif(dc, ra, imm, false_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sub_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_u_rrrc(dc, ra, rb, ext_sub_set_cc) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_sub_u_rrr(dc, ra, rb) \ __asm__("sub.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_uh_uh_u_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_uh_uh_u_rrr(dc, ra, rb) \ __asm__("mul_uh_uh.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sl_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sl_s_rrr(dc, ra, rb) \ __asm__("mul_sh_sl.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_add_s_rrri(dc, rb, ra, shift) \ __asm__("lsl_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_mul_sh_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_rrr(rc, ra, rb) \ __asm__("mul_sh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_zrr(zero, ra, rb) \ __asm__("mul_sh_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_s_rri(dc, rb, imm) __asm__("or.s %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_or_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rric(dc, ra, imm, log_set_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rrif(dc, ra, imm, false_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_s_rrr(dc, ra, rb) \ __asm__("or.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sats_rrci(rc, ra, log_nz_cc, pc) \ __asm__("sats %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zrci(zero, ra, log_nz_cc, pc) \ __asm__("sats %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_sats_rrc(rc, ra, log_set_cc) \ __asm__("sats %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zrc(zero, ra, log_set_cc) __asm__("sats %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_sats_rr(rc, ra) __asm__("sats %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_sats_zr(zero, ra) __asm__("sats %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rsub_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_u_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsub_u_rrr(dc, ra, rb) \ __asm__("rsub.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_erri(endian, rc, ra, off) \ __asm__("lw " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lw_ersi(endian, rc, sa, off) \ __asm__("lw " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_extsb_s_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extsb.s %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_s_rrc(dc, ra, log_set_cc) \ __asm__("extsb.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extsb_s_rr(dc, ra) __asm__("extsb.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rric(dc, ra, shift, log_set_cc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rri(dc, ra, shift) \ __asm__("ror.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ror_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_ror_s_rrr(dc, ra, rb) \ __asm__("ror.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_ul_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_rrr(rc, ra, rb) \ __asm__("mul_sl_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_ul_zrr(zero, ra, rb) \ __asm__("mul_sl_ul %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_s_rrci(dc, rb, true_cc, pc) \ __asm__("time_cfg.s %[dc_wr64], %[rb_wr32], " true_cc ", " pc "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_time_cfg_s_rr(dc, rb) __asm__("time_cfg.s %[dc_wr64], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_ul_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_ul_s_rrr(dc, ra, rb) \ __asm__("mul_sh_ul.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_u_rrrci(dc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_u_rrrc(dc, ra, rb, sub_set_cc) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_u_rrr(dc, ra, rb) \ __asm__("rsubc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_rol_add_rrri(rc, rb, ra, shift) \ __asm__("rol_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_rol_add_zrri(zero, rb, ra, shift) \ __asm__("rol_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_cao_rrci(rc, ra, count_nz_cc, pc) \ __asm__("cao %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zrci(zero, ra, count_nz_cc, pc) \ __asm__("cao %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_cao_rrc(rc, ra, log_set_cc) \ __asm__("cao %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zrc(zero, ra, log_set_cc) __asm__("cao %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_cao_rr(rc, ra) __asm__("cao %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_cao_zr(zero, ra) __asm__("cao %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extuh %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extuh %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rrc(rc, ra, log_set_cc) \ __asm__("extuh %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zrc(zero, ra, log_set_cc) __asm__("extuh %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extuh_rr(rc, ra) __asm__("extuh %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_zr(zero, ra) __asm__("extuh %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_mul_sl_sh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_sh_s_rrr(dc, ra, rb) \ __asm__("mul_sl_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl1_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rri(dc, ra, shift) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1_u_rrr(dc, ra, rb) \ __asm__("lsl1.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rric(dc, ra, imm, log_set_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rrif(dc, ra, imm, false_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_orn_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_s_rrr(dc, ra, rb) \ __asm__("orn.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lw_u_erri(endian, dc, ra, off) \ __asm__("lw.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_mul_sl_uh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_s_rrr(dc, ra, rb) \ __asm__("mul_sl_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lslx_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rri(dc, ra, shift) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lslx_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lslx_u_rrr(dc, ra, rb) \ __asm__("lslx.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nand_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rric(dc, ra, imm, log_set_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rrif(dc, ra, imm, false_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_s_rrr(dc, ra, rb) \ __asm__("nand.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rri(dc, ra, shift) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_u_rrr(dc, ra, rb) \ __asm__("lsr1.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_and_u_rki(dc, ra, imm) __asm__("and.u %[dc_wr64], %[ra_r32], " imm "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rri(dc, rb, imm) \ __asm__("and.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_and_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rric(dc, ra, imm, log_set_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rrif(dc, ra, imm, false_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_and_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_and_u_rrr(dc, ra, rb) \ __asm__("and.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("orn %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rric(rc, ra, imm, log_set_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zric(zero, ra, imm, log_set_cc) \ __asm__("orn %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rrif(rc, ra, imm, false_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_orn_zrif(zero, ra, imm, false_cc) __asm__("orn %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_orn_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_orn_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("orn %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrrc(rc, ra, rb, log_set_cc) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_zrrc(zero, ra, rb, log_set_cc) \ __asm__("orn %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_rrr(rc, ra, rb) \ __asm__("orn %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_orn_zrr(zero, ra, rb) __asm__("orn %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clo_rrci(rc, ra, count_nz_cc, pc) \ __asm__("clo %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zrci(zero, ra, count_nz_cc, pc) \ __asm__("clo %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_clo_rrc(rc, ra, log_set_cc) \ __asm__("clo %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zrc(zero, ra, log_set_cc) __asm__("clo %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_clo_rr(rc, ra) __asm__("clo %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clo_zr(zero, ra) __asm__("clo %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_rol_s_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rric(dc, ra, shift, log_set_cc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rri(dc, ra, shift) \ __asm__("rol.s %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_rol_s_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rol_s_rrr(dc, ra, rb) \ __asm__("rol.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_rrr(rc, ra, rb) \ __asm__("mul_sh_sh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_zrr(zero, ra, rb) \ __asm__("mul_sh_sh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rol_add_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("rol_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_rol_add_u_rrri(dc, rb, ra, shift) \ __asm__("rol_add.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_rrrici(rc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_zrrici(zero, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add %[zero], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_rrri(rc, rb, ra, shift) \ __asm__("lsr_add %[rc_wr32], %[rb_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsr_add_zrri(zero, rb, ra, shift) \ __asm__("lsr_add %[zero], %[rb_wr32], %[ra_r32], " shift "" ::[rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rric(dc, ra, imm, log_set_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrif(dc, ra, imm, false_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_hash_s_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_hash_s_rrr(dc, ra, rb) \ __asm__("hash.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_extub_rrci(rc, ra, log_nz_cc, pc) \ __asm__("extub %[rc_wr32], %[ra_r32], " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zrci(zero, ra, log_nz_cc, pc) \ __asm__("extub %[zero], %[ra_r32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_extub_rrc(rc, ra, log_set_cc) \ __asm__("extub %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zrc(zero, ra, log_set_cc) __asm__("extub %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_extub_rr(rc, ra) __asm__("extub %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_extub_zr(zero, ra) __asm__("extub %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_sw_id_erii(endian, ra, off, imm) __asm__("sw_id " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_time_rci(rc, true_cc, pc) __asm__("time %[rc_wr32], " true_cc ", " pc "" : [rc_wr32] "=r"(rc)::) #define __builtin_time_zci(zero, true_cc, pc) __asm__("time %[zero], " true_cc ", " pc "" :::) #define __builtin_time_r(rc) __asm__("time %[rc_wr32]" : [rc_wr32] "=r"(rc)::) #define __builtin_time_z(zero) __asm__("time %[zero]" :::) #define __builtin_asr_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("asr %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rric(rc, ra, shift, log_set_cc) \ __asm__("asr %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zric(zero, ra, shift, log_set_cc) \ __asm__("asr %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rri(rc, ra, shift) __asm__("asr %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_asr_zri(zero, ra, shift) __asm__("asr %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_asr_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_asr_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("asr %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_rrrc(rc, ra, rb, log_set_cc) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_zrrc(zero, ra, rb, log_set_cc) \ __asm__("asr %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_rrr(rc, ra, rb) \ __asm__("asr %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_asr_zrr(zero, ra, rb) __asm__("asr %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ldma_rri(ra, rb, immDma) \ __asm__("ldma %[ra_r32], %[rb_wr32], " immDma "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_ld_erri(endian, dc, ra, off) \ __asm__("ld " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_ld_ersi(endian, dc, sa, off) \ __asm__("ld " endian ", %[dc_wr64], %[sa_r32], " off "" : [dc_wr64] "=r"(dc) : [sa_r32] "r"(sa) :) #define __builtin_cls_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cls.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_s_rrc(dc, ra, log_set_cc) \ __asm__("cls.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cls_s_rr(dc, ra) __asm__("cls.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extuh.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rrc(dc, ra, log_set_cc) \ __asm__("extuh.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extuh_u_rr(dc, ra) __asm__("extuh.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("sats.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rrc(dc, ra, log_set_cc) \ __asm__("sats.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_sats_u_rr(dc, ra) __asm__("sats.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rric(dc, ra, imm, log_set_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrif(dc, ra, imm, false_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_addc_u_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_addc_u_rrr(dc, ra, rb) \ __asm__("addc.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rric(dc, ra, imm, log_set_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rrif(dc, ra, imm, false_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_andn_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_u_rrr(dc, ra, rb) \ __asm__("andn.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nxor_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rrif(dc, ra, imm, false_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nxor_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nxor_u_rrr(dc, ra, rb) \ __asm__("nxor.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsl_sub_u_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsl_sub.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsl_sub_u_rrri(dc, rb, ra, shift) \ __asm__("lsl_sub.u %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rrici(dc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rric(dc, ra, shift, log_set_cc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rri(dc, ra, shift) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsl1x_u_rrrci(dc, ra, rb, shift_nz_cc, pc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsl1x_u_rrr(dc, ra, rb) \ __asm__("lsl1x.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_resume_rici(ra, imm, boot_cc, pc) __asm__("resume %[ra_r32], " imm ", " boot_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lhs_erri(endian, rc, ra, off) \ __asm__("lhs " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lhs_ersi(endian, rc, sa, off) \ __asm__("lhs " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_cao_s_rrci(dc, ra, count_nz_cc, pc) \ __asm__("cao.s %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_s_rrc(dc, ra, log_set_cc) \ __asm__("cao.s %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_cao_s_rr(dc, ra) __asm__("cao.s %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rrci(dc, ra, count_nz_cc, pc) \ __asm__("clz.u %[dc_wr64], %[ra_r32], " count_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rrc(dc, ra, log_set_cc) \ __asm__("clz.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_clz_u_rr(dc, ra) __asm__("clz.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_rrici(rc, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zrici(zero, ra, shift, imm_shift_nz_cc, pc) \ __asm__("lsr1 %[zero], %[ra_r32], " shift ", " imm_shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rric(rc, ra, shift, log_set_cc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zric(zero, ra, shift, log_set_cc) \ __asm__("lsr1 %[zero], %[ra_r32], " shift ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rri(rc, ra, shift) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], " shift "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lsr1_zri(zero, ra, shift) __asm__("lsr1 %[zero], %[ra_r32], " shift "" ::[ra_r32] "r"(ra) :) #define __builtin_lsr1_rrrci(rc, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_lsr1_zrrci(zero, ra, rb, shift_nz_cc, pc) \ __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32], " shift_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_rrrc(rc, ra, rb, log_set_cc) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_zrrc(zero, ra, rb, log_set_cc) \ __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_rrr(rc, ra, rb) \ __asm__("lsr1 %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr1_zrr(zero, ra, rb) __asm__("lsr1 %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_u_rri(dc, rb, imm) \ __asm__("add.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_add_u_rrici(dc, ra, imm, add_nz_cc, pc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rric(dc, ra, imm, log_set_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rrif(dc, ra, imm, false_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_add_u_rrrci(dc, ra, rb, add_nz_cc, pc) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_u_rrr(dc, ra, rb) \ __asm__("add.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrrc(rc, ra, rb, sub_set_cc) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_rsubc_zrrc(zero, ra, rb, sub_set_cc) \ __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32], " sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_rrr(rc, ra, rb) \ __asm__("rsubc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_rsubc_zrr(zero, ra, rb) __asm__("rsubc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rri(rc, ra, imm) __asm__("add %[rc_wr32], %[ra_r32], " imm "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zri(zero, rb, imm) __asm__("add %[zero], %[rb_wr32], " imm "" ::[rb_wr32] "r"(rb) :) #define __builtin_add_rrici(rc, ra, imm, add_nz_cc, pc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " add_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zrici(zero, ra, imm, add_nz_cc, pc) \ __asm__("add %[zero], %[ra_r32], " imm ", " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_rric(rc, ra, imm, log_set_cc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zric(zero, ra, imm, log_set_cc) \ __asm__("add %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_rrif(rc, ra, imm, false_cc) \ __asm__("add %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_add_zrif(zero, ra, imm, false_cc) __asm__("add %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_add_ssi(sc, sa, imm) __asm__("add %[sc_wr32], %[sa_r32], " imm "" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa) :) #define __builtin_add_rrrci(rc, ra, rb, add_nz_cc, pc) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_add_zrrci(zero, ra, rb, add_nz_cc, pc) \ __asm__("add %[zero], %[ra_r32], %[rb_wr32], " add_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rrrc(rc, ra, rb, log_set_cc) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_zrrc(zero, ra, rb, log_set_cc) \ __asm__("add %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_rrr(rc, ra, rb) \ __asm__("add %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_zrr(zero, ra, rb) __asm__("add %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_add_sss(sc, sa, sb) \ __asm__("add %[sc_wr32], %[sa_r32], %[sb_wr32]" ::[sc_wr32] "r"(sc), [sa_r32] "r"(sa), [sb_wr32] "r"(sb) :) #define __builtin_nor_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("nor %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rric(rc, ra, imm, log_set_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zric(zero, ra, imm, log_set_cc) \ __asm__("nor %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rrif(rc, ra, imm, false_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_nor_zrif(zero, ra, imm, false_cc) __asm__("nor %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_nor_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nor_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("nor %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_rrrc(rc, ra, rb, log_set_cc) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_zrrc(zero, ra, rb, log_set_cc) \ __asm__("nor %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_rrr(rc, ra, rb) \ __asm__("nor %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_nor_zrr(zero, ra, rb) __asm__("nor %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_u_rri(dc, rb, imm) __asm__("or.u %[dc_wr64], %[rb_wr32], " imm "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb) :) #define __builtin_or_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rric(dc, ra, imm, log_set_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rrif(dc, ra, imm, false_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_or_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_or_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_or_u_rrr(dc, ra, rb) \ __asm__("or.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rir(rc, imm, ra) __asm__("subc %[rc_wr32], " imm ", %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zir(zero, imm, rb) __asm__("subc %[zero], " imm ", %[rb_wr32]" ::[rb_wr32] "r"(rb) :) #define __builtin_subc_rirci(rc, imm, ra, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirci(zero, imm, ra, sub_nz_cc, pc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rirc(rc, imm, ra, sub_set_cc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirc(zero, imm, ra, sub_set_cc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rirf(rc, imm, ra, false_cc) \ __asm__("subc %[rc_wr32], " imm ", %[ra_r32], " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zirf(zero, imm, ra, false_cc) \ __asm__("subc %[zero], " imm ", %[ra_r32], " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrici(rc, ra, imm, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zrici(zero, ra, imm, sub_nz_cc, pc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rric(rc, ra, imm, ext_sub_set_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " ext_sub_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zric(zero, ra, imm, ext_sub_set_cc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " ext_sub_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrif(rc, ra, imm, false_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_subc_zrif(zero, ra, imm, false_cc) \ __asm__("subc %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_subc_rrrci(rc, ra, rb, sub_nz_cc, pc) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_zrrci(zero, ra, rb, sub_nz_cc, pc) \ __asm__("subc %[zero], %[ra_r32], %[rb_wr32], " sub_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rrrc(rc, ra, rb, ext_sub_set_cc) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_subc_zrrc(zero, ra, rb, ext_sub_set_cc) \ __asm__("subc %[zero], %[ra_r32], %[rb_wr32], " ext_sub_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_rrr(rc, ra, rb) \ __asm__("subc %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_subc_zrr(zero, ra, rb) __asm__("subc %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lbs_erri(endian, rc, ra, off) \ __asm__("lbs " endian ", %[rc_wr32], %[ra_r32], " off "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_lbs_ersi(endian, rc, sa, off) \ __asm__("lbs " endian ", %[rc_wr32], %[sa_r32], " off "" : [rc_wr32] "=r"(rc) : [sa_r32] "r"(sa) :) #define __builtin_extub_u_rrci(dc, ra, log_nz_cc, pc) \ __asm__("extub.u %[dc_wr64], %[ra_r32], " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extub_u_rrc(dc, ra, log_set_cc) \ __asm__("extub.u %[dc_wr64], %[ra_r32], " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_extub_u_rr(dc, ra) __asm__("extub.u %[dc_wr64], %[ra_r32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrici(dc, ra, imm, log_nz_cc, pc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rric(dc, ra, imm, log_set_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " log_set_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrif(dc, ra, imm, false_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], " imm ", " false_cc "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_nand_u_rrrci(dc, ra, rb, log_nz_cc, pc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_u_rrrc(dc, ra, rb, log_set_cc) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_nand_u_rrr(dc, ra, rb) \ __asm__("nand.u %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrici(rc, ra, imm, log_nz_cc, pc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " log_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zrici(zero, ra, imm, log_nz_cc, pc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rric(rc, ra, imm, log_set_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zric(zero, ra, imm, log_set_cc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rrif(rc, ra, imm, false_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], " imm ", " false_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_andn_zrif(zero, ra, imm, false_cc) \ __asm__("andn %[zero], %[ra_r32], " imm ", " false_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_andn_rrrci(rc, ra, rb, log_nz_cc, pc) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_andn_zrrci(zero, ra, rb, log_nz_cc, pc) \ __asm__("andn %[zero], %[ra_r32], %[rb_wr32], " log_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrrc(rc, ra, rb, log_set_cc) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_zrrc(zero, ra, rb, log_set_cc) \ __asm__("andn %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_rrr(rc, ra, rb) \ __asm__("andn %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_andn_zrr(zero, ra, rb) __asm__("andn %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_release_rici(ra, imm, release_cc, pc) \ __asm__("release %[ra_r32], " imm ", " release_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_mul_sh_uh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_s_rrr(dc, ra, rb) \ __asm__("mul_sh_uh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_lsr_add_s_rrrici(dc, rb, ra, shift, div_nz_cc, pc) \ __asm__("lsr_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift ", " div_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) \ :) #define __builtin_lsr_add_s_rrri(dc, rb, ra, shift) \ __asm__("lsr_add.s %[dc_wr64], %[rb_wr32], %[ra_r32], " shift "" : [dc_wr64] "=r"(dc) : [rb_wr32] "r"(rb), [ra_r32] "r"(ra) :) #define __builtin_mul_sh_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_rrr(rc, ra, rb) \ __asm__("mul_sh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_uh_zrr(zero, ra, rb) \ __asm__("mul_sh_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrrci(rc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_zrrci(zero, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrrc(rc, ra, rb, log_set_cc) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [rc_wr32] "=r"(rc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sl_uh_zrrc(zero, ra, rb, log_set_cc) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32], " log_set_cc "" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_rrr(rc, ra, rb) \ __asm__("mul_sl_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sl_uh_zrr(zero, ra, rb) \ __asm__("mul_sl_uh %[zero], %[ra_r32], %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_mul_sh_sh_s_rrrci(dc, ra, rb, mul_nz_cc, pc) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " mul_nz_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_s_rrrc(dc, ra, rb, log_set_cc) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32], " log_set_cc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) \ :) #define __builtin_mul_sh_sh_s_rrr(dc, ra, rb) \ __asm__("mul_sh_sh.s %[dc_wr64], %[ra_r32], %[rb_wr32]" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_clz_rrci(rc, ra, count_nz_cc, pc) \ __asm__("clz %[rc_wr32], %[ra_r32], " count_nz_cc ", " pc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zrci(zero, ra, count_nz_cc, pc) \ __asm__("clz %[zero], %[ra_r32], " count_nz_cc ", " pc "" ::[ra_r32] "r"(ra) :) #define __builtin_clz_rrc(rc, ra, log_set_cc) \ __asm__("clz %[rc_wr32], %[ra_r32], " log_set_cc "" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zrc(zero, ra, log_set_cc) __asm__("clz %[zero], %[ra_r32], " log_set_cc "" ::[ra_r32] "r"(ra) :) #define __builtin_clz_rr(rc, ra) __asm__("clz %[rc_wr32], %[ra_r32]" : [rc_wr32] "=r"(rc) : [ra_r32] "r"(ra) :) #define __builtin_clz_zr(zero, ra) __asm__("clz %[zero], %[ra_r32]" ::[ra_r32] "r"(ra) :) #define __builtin_mul_step_rrrici(dc, ra, db, shift, boot_cc, pc) \ __asm__("mul_step %[dc_wr64], %[ra_r32], %[db_wr64], " shift ", " boot_cc ", " pc "" \ : [dc_wr64] "=r"(dc) \ : [ra_r32] "r"(ra), [db_wr64] "r"(db) \ :) #define __builtin_sh_erir(endian, ra, off, rb) \ __asm__("sh " endian ", %[ra_r32], " off ", %[rb_wr32]" ::[ra_r32] "r"(ra), [rb_wr32] "r"(rb) :) #define __builtin_sh_erii(endian, ra, off, imm) __asm__("sh " endian ", %[ra_r32], " off ", " imm "" ::[ra_r32] "r"(ra) :) #define __builtin_sh_esir(endian, sa, off, rb) \ __asm__("sh " endian ", %[sa_r32], " off ", %[rb_wr32]" ::[sa_r32] "r"(sa), [rb_wr32] "r"(rb) :) #define __builtin_sh_esii(endian, sa, off, imm) __asm__("sh " endian ", %[sa_r32], " off ", " imm "" ::[sa_r32] "r"(sa) :) #define __builtin_lbu_u_erri(endian, dc, ra, off) \ __asm__("lbu.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #define __builtin_lhu_u_erri(endian, dc, ra, off) \ __asm__("lhu.u " endian ", %[dc_wr64], %[ra_r32], " off "" : [dc_wr64] "=r"(dc) : [ra_r32] "r"(ra) :) #endif /* BUILT_INS_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/clzdi2.c ================================================ /* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __clzdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of leading 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __clzdi2(di_int a) { dwords x; x.all = a; const si_int f = -(x.s.high == 0); return __builtin_clz((x.s.high & ~f) | (x.s.low & f)) + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/clzsi2.c ================================================ /* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __clzsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of leading 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __clzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0xFFFF0000) == 0) << 4; /* if (x is small) t = 16 else 0 */ x >>= 16 - t; /* x = [0 - 0xFFFF] */ su_int r = t; /* r = [0, 16] */ /* return r + clz(x) */ t = ((x & 0xFF00) == 0) << 3; x >>= 8 - t; /* x = [0 - 0xFF] */ r += t; /* r = [0, 8, 16, 24] */ /* return r + clz(x) */ t = ((x & 0xF0) == 0) << 2; x >>= 4 - t; /* x = [0 - 0xF] */ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ /* return r + clz(x) */ t = ((x & 0xC) == 0) << 1; x >>= 2 - t; /* x = [0 - 3] */ r += t; /* r = [0 - 30] and is even */ /* return r + clz(x) */ /* switch (x) * { * case 0: * return r + 2; * case 1: * return r + 1; * case 2: * case 3: * return r; * } */ return r + ((2 - x) & -((x & 2) == 0)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/cmpdi2.c ================================================ /* ===-- cmpdi2.c - Implement __cmpdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __cmpdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 */ COMPILER_RT_ABI si_int __cmpdi2(di_int a, di_int b) { dwords x; x.all = a; dwords y; y.all = b; if (x.s.high < y.s.high) return 0; if (x.s.high > y.s.high) return 2; if (x.s.low < y.s.low) return 0; if (x.s.low > y.s.low) return 2; return 1; } #ifdef __ARM_EABI__ /* Returns: if (a < b) returns -1 * if (a == b) returns 0 * if (a > b) returns 1 */ COMPILER_RT_ABI si_int __aeabi_lcmp(di_int a, di_int b) { return __cmpdi2(a, b) - 1; } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/comparedf2.c ================================================ //===-- lib/comparedf2.c - Double-precision comparisons -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // // This file implements the following soft-float comparison routines: // // __eqdf2 __gedf2 __unorddf2 // __ledf2 __gtdf2 // __ltdf2 // __nedf2 // // The semantics of the routines grouped in each column are identical, so there // is a single implementation for each, and wrappers to provide the other names. // // The main routines behave as follows: // // __ledf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // 1 if either a or b is NaN // // __gedf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // -1 if either a or b is NaN // // __unorddf2(a,b) returns 0 if both a and b are numbers // 1 if either a or b is NaN // // Note that __ledf2( ) and __gedf2( ) are identical except in their handling of // NaN values. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 }; COMPILER_RT_ABI enum LE_RESULT __ledf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; // If either a or b is NaN, they are unordered. if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; // If a and b are both zeros, they are equal. if ((aAbs | bAbs) == 0) return LE_EQUAL; // If at least one of a and b is positive, we get the same result comparing // a and b as signed integers as we would with a floating-point compare. if ((aInt & bInt) >= 0) { if (aInt < bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } // Otherwise, both are negative, so we need to flip the sense of the // comparison to get the correct result. (This assumes a twos- or ones- // complement integer representation; if integers are represented in a // sign-magnitude representation, then this flip is incorrect). else { if (aInt > bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } } #if defined(__ELF__) // Alias for libgcc compatibility FNALIAS(__cmpdf2, __ledf2); #endif enum GE_RESULT { GE_LESS = -1, GE_EQUAL = 0, GE_GREATER = 1, GE_UNORDERED = -1 // Note: different from LE_UNORDERED }; COMPILER_RT_ABI enum GE_RESULT __gedf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; if ((aAbs | bAbs) == 0) return GE_EQUAL; if ((aInt & bInt) >= 0) { if (aInt < bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } else { if (aInt > bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } } COMPILER_RT_ABI int __unorddf2(fp_t a, fp_t b) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; return aAbs > infRep || bAbs > infRep; } // The following are alternative names for the preceding routines. COMPILER_RT_ABI enum LE_RESULT __eqdf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __ltdf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __nedf2(fp_t a, fp_t b) { return __ledf2(a, b); } COMPILER_RT_ABI enum GE_RESULT __gtdf2(fp_t a, fp_t b) { return __gedf2(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI int __aeabi_dcmpun(fp_t a, fp_t b) { return __unorddf2(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/comparesf2.c ================================================ //===-- lib/comparesf2.c - Single-precision comparisons -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the following soft-fp_t comparison routines: // // __eqsf2 __gesf2 __unordsf2 // __lesf2 __gtsf2 // __ltsf2 // __nesf2 // // The semantics of the routines grouped in each column are identical, so there // is a single implementation for each, and wrappers to provide the other names. // // The main routines behave as follows: // // __lesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // 1 if either a or b is NaN // // __gesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // -1 if either a or b is NaN // // __unordsf2(a,b) returns 0 if both a and b are numbers // 1 if either a or b is NaN // // Note that __lesf2( ) and __gesf2( ) are identical except in their handling of // NaN values. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" enum LE_RESULT { LE_LESS = -1, LE_EQUAL = 0, LE_GREATER = 1, LE_UNORDERED = 1 }; COMPILER_RT_ABI enum LE_RESULT __lesf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; // If either a or b is NaN, they are unordered. if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED; // If a and b are both zeros, they are equal. if ((aAbs | bAbs) == 0) return LE_EQUAL; // If at least one of a and b is positive, we get the same result comparing // a and b as signed integers as we would with a fp_ting-point compare. if ((aInt & bInt) >= 0) { if (aInt < bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } // Otherwise, both are negative, so we need to flip the sense of the // comparison to get the correct result. (This assumes a twos- or ones- // complement integer representation; if integers are represented in a // sign-magnitude representation, then this flip is incorrect). else { if (aInt > bInt) return LE_LESS; else if (aInt == bInt) return LE_EQUAL; else return LE_GREATER; } } #if defined(__ELF__) // Alias for libgcc compatibility FNALIAS(__cmpsf2, __lesf2); #endif enum GE_RESULT { GE_LESS = -1, GE_EQUAL = 0, GE_GREATER = 1, GE_UNORDERED = -1 // Note: different from LE_UNORDERED }; COMPILER_RT_ABI enum GE_RESULT __gesf2(fp_t a, fp_t b) { const srep_t aInt = toRep(a); const srep_t bInt = toRep(b); const rep_t aAbs = aInt & absMask; const rep_t bAbs = bInt & absMask; if (aAbs > infRep || bAbs > infRep) return GE_UNORDERED; if ((aAbs | bAbs) == 0) return GE_EQUAL; if ((aInt & bInt) >= 0) { if (aInt < bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } else { if (aInt > bInt) return GE_LESS; else if (aInt == bInt) return GE_EQUAL; else return GE_GREATER; } } COMPILER_RT_ABI int __unordsf2(fp_t a, fp_t b) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; return aAbs > infRep || bAbs > infRep; } // The following are alternative names for the preceding routines. COMPILER_RT_ABI enum LE_RESULT __eqsf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __ltsf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum LE_RESULT __nesf2(fp_t a, fp_t b) { return __lesf2(a, b); } COMPILER_RT_ABI enum GE_RESULT __gtsf2(fp_t a, fp_t b) { return __gesf2(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI int __aeabi_fcmpun(fp_t a, fp_t b) { return __unordsf2(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ctzdi2.c ================================================ /* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ctzdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of trailing 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __ctzdi2(di_int a) { dwords x; x.all = a; const si_int f = -(x.s.low == 0); return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) + (f & ((si_int)(sizeof(si_int) * CHAR_BIT))); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ctzsi2.c ================================================ /* ===-- ctzsi2.c - Implement __ctzsi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ctzsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the number of trailing 0-bits */ /* Precondition: a != 0 */ COMPILER_RT_ABI si_int __ctzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0x0000FFFF) == 0) << 4; /* if (x has no small bits) t = 16 else 0 */ x >>= t; /* x = [0 - 0xFFFF] + higher garbage bits */ su_int r = t; /* r = [0, 16] */ /* return r + ctz(x) */ t = ((x & 0x00FF) == 0) << 3; x >>= t; /* x = [0 - 0xFF] + higher garbage bits */ r += t; /* r = [0, 8, 16, 24] */ /* return r + ctz(x) */ t = ((x & 0x0F) == 0) << 2; x >>= t; /* x = [0 - 0xF] + higher garbage bits */ r += t; /* r = [0, 4, 8, 12, 16, 20, 24, 28] */ /* return r + ctz(x) */ t = ((x & 0x3) == 0) << 1; x >>= t; x &= 3; /* x = [0 - 3] */ r += t; /* r = [0 - 30] and is even */ /* return r + ctz(x) */ /* The branch-less return statement below is equivalent * to the following switch statement: * switch (x) * { * case 0: * return r + 2; * case 2: * return r + 1; * case 1: * case 3: * return r; * } */ return r + ((2 - (x >> 1)) & -((x & 1) == 0)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/defs.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include int check_stack() { unsigned int stack_base, stack_size; int stack_limit, remaining; thread_id_t tid = me(); stack_base = __SP_TABLE__[tid].stack_ptr; stack_size = __SP_TABLE__[tid].stack_size; stack_limit = (int)(stack_base + stack_size); __asm__ volatile("sub %[r], %[l], r22" : [r] "=r"(remaining) : [l] "r"(stack_limit)); return remaining; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/defs.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DEFS_H #define DPUSYSCORE_DEFS_H #include #include #include #include /** * @file defs.h * @brief Miscellaneous system functions. * * General purpose definitions. */ #if __STDC_VERSION__ >= 201112L #define __ATTRIBUTE_NO_RETURN__ _Noreturn #else #define __ATTRIBUTE_NO_RETURN__ #endif /* __STDC_VERSION__ */ /** * @fn me * @internal This just returns the value of the special register id. * @return The current tasklet's sysname. */ static inline sysname_t me() { return __builtin_dpu_tid(); } /** * @fn halt * @brief Halts the DPU. * @throws FAULT_HALT always */ __ATTRIBUTE_NO_RETURN__ static inline void halt() { __builtin_trap(); __builtin_unreachable(); } /** * @fn check_stack * @return the number of unused 32-bits words in the current runtime's stack. * If the number is negative, it indicates by how much 32-bits words the stack overflowed. * * @internal This fetches the position of the next stack in memory from the Stack Pointer Table (cf. tasklet.h) * and compute the remaining bytes. */ int check_stack(); #endif /* DPUSYSCORE_DEFS_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/devprivate.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DEVPRIVATE_H #define DPUSYSCORE_DEVPRIVATE_H /** * @file devprivate.h * @brief Reserved for internal use ... please do not use those functions unless you know exactly what you do. */ /** * @def tell * @brief On a simulator, injects a tell instruction to print out developer debug info. * @nolink * * @warning This function will not work on a target different from simulator. * * @param reg a register * @param val a constant value */ #define tell(reg, val) __asm__("tell %[r], " val : : [r] "r"(reg) :) #endif /* DPUSYSCORE_DEVPRIVATE_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/div32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include void __attribute__((naked, noinline, no_instrument_function)) __udiv32(void) { __asm__ volatile(" "__ADD_PROFILING_ENTRY__ " clz r3, r1, max, __udiv32_division_by_zero\n" // r3 = by how many the divider can be shifted on 32-bit " clz r4, r0\n" // r4 = number of useless bits of the dividend " sub r3, r4, r3, gtu, __udiv32_result_0\n" // r3 = the maximal shift to be done " move r4, r1\n" " move.u d0, r0\n" " jump r3, __udiv32_base\n" // As we will jump backward relatively to __udiv32_base " div_step d0, r4, d0, 31\n" " div_step d0, r4, d0, 30\n" " div_step d0, r4, d0, 29\n" " div_step d0, r4, d0, 28\n" " div_step d0, r4, d0, 27\n" " div_step d0, r4, d0, 26\n" " div_step d0, r4, d0, 25\n" " div_step d0, r4, d0, 24\n" " div_step d0, r4, d0, 23\n" " div_step d0, r4, d0, 22\n" " div_step d0, r4, d0, 21\n" " div_step d0, r4, d0, 20\n" " div_step d0, r4, d0, 19\n" " div_step d0, r4, d0, 18\n" " div_step d0, r4, d0, 17\n" " div_step d0, r4, d0, 16\n" " div_step d0, r4, d0, 15\n" " div_step d0, r4, d0, 14\n" " div_step d0, r4, d0, 13\n" " div_step d0, r4, d0, 12\n" " div_step d0, r4, d0, 11\n" " div_step d0, r4, d0, 10\n" " div_step d0, r4, d0, 9\n" " div_step d0, r4, d0, 8\n" " div_step d0, r4, d0, 7\n" " div_step d0, r4, d0, 6\n" " div_step d0, r4, d0, 5\n" " div_step d0, r4, d0, 4\n" " div_step d0, r4, d0, 3\n" " div_step d0, r4, d0, 2\n" " div_step d0, r4, d0, 1\n" "__udiv32_base:\n" " div_step d0, r4, d0, 0\n" "__udiv32_exit:\n" " jump r23\n" "__udiv32_result_0:\n" " move.u d0, r0, true, __udiv32_exit\n" "__udiv32_division_by_zero:\n" " fault "__STR(__FAULT_DIVISION_BY_ZERO__)); } void __attribute__((naked, noinline, no_instrument_function)) __div32(void) { __asm__ volatile(" "__ADD_PROFILING_ENTRY__ "sd r22, 0, d22\n" "add r22, r22, 8\n" // The quotient's sign depends on the sign of the dividend and divider... After few tries it sounds // like the quickest way to select the operators is to branch according to the cases. " clo r3, r0, z, __div32_pos_dividend\n" " clo r3, r1, z, __div32_neg_dividend_pos_divider\n" "__div32_neg_dividend_neg_divider:\n" // As a result, the quotient is positive and the remainder negative " neg r0, r0\n" " neg r1, r1\n" " call r23, __udiv32\n" " neg r1, r1, true, __div32_exit\n" "__div32_neg_dividend_pos_divider:\n" // As a result, the quotient is negative and the remainder negative " neg r0, r0\n" " call r23, __udiv32\n" " neg r1, r1\n" " neg r0, r0, true, __div32_exit\n" "__div32_pos_dividend:\n" " clo r3, r1, z, __div32_pos_dividend_pos_divider\n" " neg r1, r1\n" // As a result, the quotient is negative and the remainder positive " call r23, __udiv32\n" " neg r0, r0, true, __div32_exit\n" "__div32_pos_dividend_pos_divider:\n" // The dividend and divider are both positive " call r23, __udiv32\n" "__div32_exit:\n" " ld d22, r22, -8\n" " jump r23\n"); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/divdf3.c ================================================ //===-- lib/divdf3.c - Double-precision division ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float division // with the IEEE-754 default rounding (to nearest, ties to even). // // For simplicity, this implementation currently flushes denormals to zero. // It should be a fairly straightforward exercise to implement gradual // underflow with correct rounding. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __divdf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent - 1U >= maxExponent - 1U || bExponent - 1U >= maxExponent - 1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN / anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything / NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity / infinity = NaN if (bAbs == infRep) return fromRep(qnanRep); // infinity / anything else = +/- infinity else return fromRep(aAbs | quotientSign); } // anything else / infinity = +/- 0 if (bAbs == infRep) return fromRep(quotientSign); if (!aAbs) { // zero / zero = NaN if (!bAbs) return fromRep(qnanRep); // zero / anything else = +/- zero else return fromRep(quotientSign); } // anything else / zero = +/- infinity if (!bAbs) return fromRep(infRep | quotientSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale -= normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; int quotientExponent = aExponent - bExponent + scale; // Align the significand of b as a Q31 fixed-point number in the range // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // is accurate to about 3.5 binary digits. const uint32_t q31b = bSignificand >> 21; uint32_t recip32 = UINT32_C(0x7504f333) - q31b; // Now refine the reciprocal estimate using a Newton-Raphson iteration: // // x1 = x0 * (2 - x0 * b) // // This doubles the number of correct binary digits in the approximation // with each iteration, so after three iterations, we have about 28 binary // digits of accuracy. uint32_t correction32; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; correction32 = -((uint64_t)recip32 * q31b >> 32); recip32 = (uint64_t)recip32 * correction32 >> 31; // recip32 might have overflowed to exactly zero in the preceding // computation if the high word of b is exactly 1.0. This would sabotage // the full-width final stage of the computation that follows, so we adjust // recip32 downward by one bit. recip32--; // We need to perform one more iteration to get us to 56 binary digits; // The last iteration needs to happen with extra precision. const uint32_t q63blo = bSignificand << 11; uint64_t correction, reciprocal; correction = -((uint64_t)recip32 * q31b + ((uint64_t)recip32 * q63blo >> 32)); uint32_t cHi = correction >> 32; uint32_t cLo = correction; reciprocal = (uint64_t)recip32 * cHi + ((uint64_t)recip32 * cLo >> 32); // We already adjusted the 32-bit estimate, now we need to adjust the final // 64-bit reciprocal estimate downward to ensure that it is strictly smaller // than the infinitely precise exact reciprocal. Because the computation // of the Newton-Raphson step is truncating at every step, this adjustment // is small; most of the work is already done. reciprocal -= 2; // The numerical reciprocal is accurate to within 2^-56, lies in the // interval [0.5, 1.0), and is strictly smaller than the true reciprocal // of b. Multiplying a by this reciprocal thus gives a numerical q = a/b // in Q53 with the following properties: // // 1. q < a/b // 2. q is in the interval [0.5, 2.0) // 3. the error in q is bounded away from 2^-53 (actually, we have a // couple of bits to spare, but this is all we need). // We need a 64 x 64 multiply high to compute q, which isn't a basic // operation in C, so we need to be a little bit fussy. rep_t quotient, quotientLo; wideMultiply(aSignificand << 2, reciprocal, "ient, "ientLo); // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). // In either case, we are going to compute a residual of the form // // r = a - q*b // // We know from the construction of q that r satisfies: // // 0 <= r < ulp(q)*b // // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we // already have the correct result. The exact halfway case cannot occur. // We also take this time to right shift quotient if it falls in the [1,2) // range and adjust the exponent accordingly. rep_t residual; if (quotient < (implicitBit << 1)) { residual = (aSignificand << 53) - quotient * bSignificand; quotientExponent--; } else { quotient >>= 1; residual = (aSignificand << 52) - quotient * bSignificand; } const int writtenExponent = quotientExponent + exponentBias; if (writtenExponent >= maxExponent) { // If we have overflowed the exponent, return infinity. return fromRep(infRep | quotientSign); } else if (writtenExponent < 1) { // Flush denormals to zero. In the future, it would be nice to add // code to round them correctly. return fromRep(quotientSign); } else { const bool round = (residual << 1) > bSignificand; // Clear the implicit bit rep_t absResult = quotient & significandMask; // Insert the exponent absResult |= (rep_t)writtenExponent << significandBits; // Round absResult += round; // Insert the sign and return const double result = fromRep(absResult | quotientSign); return result; } } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ddiv(fp_t a, fp_t b) { return __divdf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/divdi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 signed division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); int64_t __divdi3(int64_t dividend, int64_t divider) { if (dividend >= 0) { if (divider >= 0) { return __udiv64(dividend, divider, 0); } else { return -__udiv64(dividend, -divider, 0); } } else if (divider >= 0) { // Negative dividend, positive divider return -__udiv64(-dividend, divider, 0); } else { // Negative dividend, negative divider return __udiv64(-dividend, -divider, 0); } } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/divmodsi4.c ================================================ /*===-- divmodsi4.c - Implement __divmodsi4 --------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __divmodsi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b, *rem = a % b */ extern long __div32(int, int); COMPILER_RT_ABI si_int __divmodsi4(si_int a, si_int b, si_int *rem) { long res = __div32(a, b); *rem = (int)res; return (int)(res >> 32); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/divsf3.c ================================================ //===-- lib/divsf3.c - Single-precision division ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float division // with the IEEE-754 default rounding (to nearest, ties to even). // // For simplicity, this implementation currently flushes denormals to zero. // It should be a fairly straightforward exercise to implement gradual // underflow with correct rounding. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __divsf3(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t quotientSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent - 1U >= maxExponent - 1U || bExponent - 1U >= maxExponent - 1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN / anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything / NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity / infinity = NaN if (bAbs == infRep) return fromRep(qnanRep); // infinity / anything else = +/- infinity else return fromRep(aAbs | quotientSign); } // anything else / infinity = +/- 0 if (bAbs == infRep) return fromRep(quotientSign); if (!aAbs) { // zero / zero = NaN if (!bAbs) return fromRep(qnanRep); // zero / anything else = +/- zero else return fromRep(quotientSign); } // anything else / zero = +/- infinity if (!bAbs) return fromRep(infRep | quotientSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale -= normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; int quotientExponent = aExponent - bExponent + scale; // Align the significand of b as a Q31 fixed-point number in the range // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // is accurate to about 3.5 binary digits. uint32_t q31b = bSignificand << 8; uint32_t reciprocal = UINT32_C(0x7504f333) - q31b; // Now refine the reciprocal estimate using a Newton-Raphson iteration: // // x1 = x0 * (2 - x0 * b) // // This doubles the number of correct binary digits in the approximation // with each iteration, so after three iterations, we have about 28 binary // digits of accuracy. uint32_t correction; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; correction = -((uint64_t)reciprocal * q31b >> 32); reciprocal = (uint64_t)reciprocal * correction >> 31; // Exhaustive testing shows that the error in reciprocal after three steps // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our // expectations. We bump the reciprocal by a tiny value to force the error // to be strictly positive (in the range [0x1.4fdfp-37,0x1.287246p-29], to // be specific). This also causes 1/1 to give a sensible approximation // instead of zero (due to overflow). reciprocal -= 2; // The numerical reciprocal is accurate to within 2^-28, lies in the // interval [0x1.000000eep-1, 0x1.fffffffcp-1], and is strictly smaller // than the true reciprocal of b. Multiplying a by this reciprocal thus // gives a numerical q = a/b in Q24 with the following properties: // // 1. q < a/b // 2. q is in the interval [0x1.000000eep-1, 0x1.fffffffcp0) // 3. the error in q is at most 2^-24 + 2^-27 -- the 2^24 term comes // from the fact that we truncate the product, and the 2^27 term // is the error in the reciprocal of b scaled by the maximum // possible value of a. As a consequence of this error bound, // either q or nextafter(q) is the correctly rounded rep_t quotient = (uint64_t)reciprocal * (aSignificand << 1) >> 32; // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). // In either case, we are going to compute a residual of the form // // r = a - q*b // // We know from the construction of q that r satisfies: // // 0 <= r < ulp(q)*b // // if r is greater than 1/2 ulp(q)*b, then q rounds up. Otherwise, we // already have the correct result. The exact halfway case cannot occur. // We also take this time to right shift quotient if it falls in the [1,2) // range and adjust the exponent accordingly. rep_t residual; if (quotient < (implicitBit << 1)) { residual = (aSignificand << 24) - quotient * bSignificand; quotientExponent--; } else { quotient >>= 1; residual = (aSignificand << 23) - quotient * bSignificand; } const int writtenExponent = quotientExponent + exponentBias; if (writtenExponent >= maxExponent) { // If we have overflowed the exponent, return infinity. return fromRep(infRep | quotientSign); } else if (writtenExponent < 1) { // Flush denormals to zero. In the future, it would be nice to add // code to round them correctly. return fromRep(quotientSign); } else { const bool round = (residual << 1) > bSignificand; // Clear the implicit bit rep_t absResult = quotient & significandMask; // Insert the exponent absResult |= (rep_t)writtenExponent << significandBits; // Round absResult += round; // Insert the sign and return return fromRep(absResult | quotientSign); } } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fdiv(fp_t a, fp_t b) { return __divsf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/divsi3.c ================================================ /* ===-- divsi3.c - Implement __divsi3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __divsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b */ COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) { const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1; si_int s_a = a >> bits_in_word_m1; /* s_a = a < 0 ? -1 : 0 */ si_int s_b = b >> bits_in_word_m1; /* s_b = b < 0 ? -1 : 0 */ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ s_a ^= s_b; /* sign of quotient */ /* * On CPUs without unsigned hardware division support, * this calls __udivsi3 (notice the cast to su_int). * On CPUs with unsigned hardware division support, * this uses the unsigned division instruction. */ return ((su_int)a / (su_int)b ^ s_a) - s_a; /* negate if s_a == -1 */ } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_idiv(si_int a, si_int b) { return __divsi3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/dpuconst.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPUCONST_H #define DPUSYSCORE_DPUCONST_H #define __DPU_NUMBER_OF_THREADS 24 #define __DPU_MRAM_SIZE_LOG2 26 #endif /* DPUSYSCORE_DPUCONST_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/dpufault.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPUFAULT_H #define DPUSYSCORE_DPUFAULT_H // A list of "fault codes" #define __FAULT_ALLOC_HEAP_FULL__ 1 #define __FAULT_DIVISION_BY_ZERO__ 2 #define __FAULT_ASSERT_FAILED__ 3 // Used in the compiler to implement a trap #define __FAULT_HALT__ 4 #define __FAULT_PRINTF_OVERFLOW__ 5 #define __FAULT_ALREADY_PROFILING__ 6 #define __FAULT_NOT_PROFILING__ 7 #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/dpuruntime.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_DPURUNTIME_H #define DPUSYSCORE_DPURUNTIME_H #include #include #include #include #include // todo fix: This file should not be included by another syslib header file, only by source files (conflicting definitions). #define __INITIAL_HEAP_POINTER __sys_heap_pointer_reset #define __HEAP_POINTER __sys_heap_pointer #define __WAIT_QUEUE_TABLE __sys_wq_table #define __SP_TABLE__ __sys_thread_stack_table_ptr #define __STDOUT_BUFFER_STATE __stdout_buffer_state /* The order needs to match the __bootstrap function expectation */ typedef struct { uint32_t stack_size; uint32_t stack_ptr; } thread_stack_t; extern unsigned int __INITIAL_HEAP_POINTER; extern volatile unsigned int __HEAP_POINTER; extern unsigned char __WAIT_QUEUE_TABLE[]; extern thread_stack_t __SP_TABLE__[]; #define __acquire(base, off) __builtin_acquire_rici(base, off, "nz", __AT_THIS_INSTRUCTION) #define __release(base, off, at) __builtin_release_rici(base, off, "nz", at) #define __resume(base, off) __builtin_resume_rici(base, off, "nz", __AT_THIS_INSTRUCTION) #define __stop() __builtin_stop_ci("false", "0") #define __stop_at(label) __builtin_stop_ci("true", label) #define likely(x) __builtin_expect((x), 1) #define unlikely(x) __builtin_expect((x), 0) #define unreachable() __builtin_unreachable() #define count_leading_zeros(x) __builtin_clz(x) #define count_population(x) __builtin_popcount(x) #define __EMPTY_WAIT_QUEUE 0xFF #define __AT_THIS_INSTRUCTION ".+0" #define __AT_NEXT_INSTRUCTION ".+1" // Use this macro at the beginning of an assembly function in order to get profiled. #ifdef DPU_PROFILING #define __ADD_PROFILING_ENTRY__ "call r23, mcount\n" #else #define __ADD_PROFILING_ENTRY__ "\n" #endif #ifdef DPU_PROFILING /* Reset counter + count cycles */ #define __CONFIG_PERFCOUNTER_ENTRY__ \ " move r23, 3\n" \ " time_cfg zero, r23\n" #define __SAVE_PERFCOUNTER_ENTRY__ \ " time r23\n" \ " sw zero, perfcounter_end_value, r23\n" #else #define __CONFIG_PERFCOUNTER_ENTRY__ "\n" #define __SAVE_PERFCOUNTER_ENTRY__ "\n" #endif #endif /* DPUSYSCORE_DPURUNTIME_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/extendhfsf2.c ================================================ //===-- lib/extendhfsf2.c - half -> single conversion -------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // #define SRC_HALF #define DST_SINGLE #include "fp_extend_impl.inc" // Use a forwarding definition and noinline to implement a poor man's alias, // as there isn't a good cross-platform way of defining one. COMPILER_RT_ABI NOINLINE float __extendhfsf2(uint16_t a) { return __extendXfYf2__(a); } COMPILER_RT_ABI float __gnu_h2f_ieee(uint16_t a) { return __extendhfsf2(a); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_h2f(uint16_t a) { return __extendhfsf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/extendsfdf2.c ================================================ //===-- lib/extendsfdf2.c - single -> double conversion -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // #define SRC_SINGLE #define DST_DOUBLE #include "fp_extend_impl.inc" COMPILER_RT_ABI double __extendsfdf2(float a) { return __extendXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_f2d(float a) { return __extendsfdf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ffsdi2.c ================================================ /* ===-- ffsdi2.c - Implement __ffsdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffsdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffsdi2(di_int a) { dwords x; x.all = a; if (x.s.low == 0) { if (x.s.high == 0) return 0; return __builtin_ctz(x.s.high) + (1 + sizeof(si_int) * CHAR_BIT); } return __builtin_ctz(x.s.low) + 1; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ffssi2.c ================================================ /* ===-- ffssi2.c - Implement __ffssi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffssi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffssi2(si_int a) { if (a == 0) { return 0; } return __builtin_ctz(a) + 1; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ffsti2.c ================================================ /* ===-- ffsti2.c - Implement __ffsti2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ffsti2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #ifdef CRT_HAS_128BIT /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ COMPILER_RT_ABI si_int __ffsti2(ti_int a) { twords x; x.all = a; if (x.s.low == 0) { if (x.s.high == 0) return 0; return __builtin_ctzll(x.s.high) + (1 + sizeof(di_int) * CHAR_BIT); } return __builtin_ctzll(x.s.low) + 1; } #endif /* CRT_HAS_128BIT */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixdfdi.c ================================================ /* ===-- fixdfdi.c - Implement __fixdfdi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunsdfdi(double a); COMPILER_RT_ABI di_int __fixdfdi(double a) { if (a < 0.0) { return -__fixunsdfdi(-a); } return __fixunsdfdi(a); } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI di_int __fixdfdi(fp_t a) { return __fixint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI di_int #if defined(__SOFT_FP__) __aeabi_d2lz(fp_t a) { #else __aeabi_d2lz(double a) { #endif return __fixdfdi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixdfsi.c ================================================ /* ===-- fixdfsi.c - Implement __fixdfsi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" typedef si_int fixint_t; typedef su_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI si_int __fixdfsi(fp_t a) { return __fixint(a); } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_d2iz(fp_t a) { return __fixdfsi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixsfdi.c ================================================ /* ===-- fixsfdi.c - Implement __fixsfdi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunssfdi(float a); COMPILER_RT_ABI di_int __fixsfdi(float a) { if (a < 0.0f) { return -__fixunssfdi(-a); } return __fixunssfdi(a); } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI di_int __fixsfdi(fp_t a) { return __fixint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI di_int #if defined(__SOFT_FP__) __aeabi_f2lz(fp_t a) { #else __aeabi_f2lz(float a) { #endif return __fixsfdi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixsfsi.c ================================================ /* ===-- fixsfsi.c - Implement __fixsfsi -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" typedef si_int fixint_t; typedef su_int fixuint_t; #include "fp_fixint_impl.inc" COMPILER_RT_ABI si_int __fixsfsi(fp_t a) { return __fixint(a); } #if defined(__ARM_EABI__) AEABI_RTABI si_int __aeabi_f2iz(fp_t a) { return __fixsfsi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixunsdfdi.c ================================================ /* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunsdfdi(double a) { if (a <= 0.0) return 0; su_int high = a / 4294967296.f; /* a / 0x1p32f; */ su_int low = a - (double)high * 4294967296.f; /* high * 0x1p32f; */ return ((du_int)high << 32) | low; } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef du_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI du_int __fixunsdfdi(fp_t a) { return __fixuint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI du_int #if defined(__SOFT_FP__) __aeabi_d2ulz(fp_t a) { #else __aeabi_d2ulz(double a) { #endif return __fixunsdfdi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixunsdfsi.c ================================================ /* ===-- fixunsdfsi.c - Implement __fixunsdfsi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define DOUBLE_PRECISION #include "fp_lib.h" typedef su_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI su_int __fixunsdfsi(fp_t a) { return __fixuint(a); } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_d2uiz(fp_t a) { return __fixunsdfsi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixunssfdi.c ================================================ /* ===-- fixunssfdi.c - Implement __fixunssfdi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; can set the invalid * flag as a side-effect of computation. */ COMPILER_RT_ABI du_int __fixunssfdi(float a) { if (a <= 0.0f) return 0; double da = a; su_int high = da / 4294967296.f; /* da / 0x1p32f; */ su_int low = da - (double)high * 4294967296.f; /* high * 0x1p32f; */ return ((du_int)high << 32) | low; } #else /* Support for systems that don't have hardware floating-point; there are no * flags to set, and we don't want to code-gen to an unknown soft-float * implementation. */ typedef du_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI du_int __fixunssfdi(fp_t a) { return __fixuint(a); } #endif #if defined(__ARM_EABI__) AEABI_RTABI du_int #if defined(__SOFT_FP__) __aeabi_f2ulz(fp_t a) { #else __aeabi_f2ulz(float a) { #endif return __fixunssfdi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fixunssfsi.c ================================================ /* ===-- fixunssfsi.c - Implement __fixunssfsi -----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __fixunssfsi for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #define SINGLE_PRECISION #include "fp_lib.h" typedef su_int fixuint_t; #include "fp_fixuint_impl.inc" COMPILER_RT_ABI su_int __fixunssfsi(fp_t a) { return __fixuint(a); } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_f2uiz(fp_t a) { return __fixunssfsi(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/float.h ================================================ /*===---- float.h - Characteristics of floating point types ----------------=== * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * *===-----------------------------------------------------------------------=== */ #ifndef __FLOAT_H #define __FLOAT_H /** * @file float.h */ /* Characteristics of floating point types, C99 5.2.4.2.2 */ #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ #define FLT_ROUNDS (__builtin_flt_rounds()) #define FLT_RADIX __FLT_RADIX__ #define FLT_MANT_DIG __FLT_MANT_DIG__ #define DBL_MANT_DIG __DBL_MANT_DIG__ #define LDBL_MANT_DIG __LDBL_MANT_DIG__ #if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) #define DECIMAL_DIG __DECIMAL_DIG__ #endif #define FLT_DIG __FLT_DIG__ #define DBL_DIG __DBL_DIG__ #define LDBL_DIG __LDBL_DIG__ #define FLT_MIN_EXP __FLT_MIN_EXP__ #define DBL_MIN_EXP __DBL_MIN_EXP__ #define LDBL_MIN_EXP __LDBL_MIN_EXP__ #define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ #define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ #define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ #define FLT_MAX_EXP __FLT_MAX_EXP__ #define DBL_MAX_EXP __DBL_MAX_EXP__ #define LDBL_MAX_EXP __LDBL_MAX_EXP__ #define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ #define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ #define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ #define FLT_MAX __FLT_MAX__ #define DBL_MAX __DBL_MAX__ #define LDBL_MAX __LDBL_MAX__ #define FLT_EPSILON __FLT_EPSILON__ #define DBL_EPSILON __DBL_EPSILON__ #define LDBL_EPSILON __LDBL_EPSILON__ #define FLT_MIN __FLT_MIN__ #define DBL_MIN __DBL_MIN__ #define LDBL_MIN __LDBL_MIN__ #define FLT_HAS_SUBNORM (-1) #define DBL_HAS_SUBNORM (-1) #define LDBL_HAS_SUBNORM (-1) #define DBL_FLT_HAS_SUBNORM (-1) #define LDBL_FLT_HAS_SUBNORM (-1) #if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) #define FLT_TRUE_MIN __FLT_DENORM_MIN__ #define DBL_TRUE_MIN __DBL_DENORM_MIN__ #define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ #define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__ #define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__ #define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__ #endif #endif /* __FLOAT_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatdidf.c ================================================ /*===-- floatdidf.c - Implement __floatdidf -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __floatdidf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: convert a to a double, rounding toward even. */ /* Assumption: double is a IEEE 64 bit floating point type * di_int is a 64 bit integral type */ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. */ COMPILER_RT_ABI double __floatdidf(di_int a) { static const double twop52 = 4503599627370496.0; // 0x1.0p52 static const double twop32 = 4294967296.0; // 0x1.0p32 union { int64_t x; double d; } low = { .d = twop52 }; const double high = (int32_t)(a >> 32) * twop32; low.x |= a & INT64_C(0x00000000ffffffff); const double result = (high - twop52) + low.d; return result; } #else /* Support for systems that don't have hardware floating-point; there are no flags to * set, and we don't want to code-gen to an unknown soft-float implementation. */ COMPILER_RT_ABI double __floatdidf(di_int a) { if (a == 0) return 0.0; const unsigned N = sizeof(di_int) * CHAR_BIT; const di_int s = a >> (N - 1); a = (a ^ s) - s; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > DBL_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit DBL_MANT_DIG-1 bits to the right of 1 * Q = bit DBL_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case DBL_MANT_DIG + 1: a <<= 1; break; case DBL_MANT_DIG + 2: break; default: a = ((du_int)a >> (sd - (DBL_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ if (a & ((du_int)1 << DBL_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to DBL_MANT_DIG bits */ } else { a <<= (DBL_MANT_DIG - sd); /* a is now rounded to DBL_MANT_DIG bits */ } double_bits fb; fb.u.s.high = ((su_int)s & 0x80000000) | /* sign */ ((e + 1023) << 20) | /* exponent */ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ fb.u.s.low = (su_int)a; /* mantissa-low */ return fb.f; } #endif #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_l2d(di_int a) { return __floatdidf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatdisf.c ================================================ /*===-- floatdisf.c - Implement __floatdisf -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * *===----------------------------------------------------------------------=== * * This file implements __floatdisf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ /* Returns: convert a to a float, rounding toward even.*/ /* Assumption: float is a IEEE 32 bit floating point type * di_int is a 64 bit integral type */ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" COMPILER_RT_ABI float __floatdisf(di_int a) { if (a == 0) return 0.0F; const unsigned N = sizeof(di_int) * CHAR_BIT; const di_int s = a >> (N - 1); a = (a ^ s) - s; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > FLT_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit FLT_MANT_DIG-1 bits to the right of 1 * Q = bit FLT_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case FLT_MANT_DIG + 1: a <<= 1; break; case FLT_MANT_DIG + 2: break; default: a = ((du_int)a >> (sd - (FLT_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ if (a & ((du_int)1 << FLT_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to FLT_MANT_DIG bits */ } else { a <<= (FLT_MANT_DIG - sd); /* a is now rounded to FLT_MANT_DIG bits */ } float_bits fb; fb.u = ((su_int)s & 0x80000000) | /* sign */ ((e + 127) << 23) | /* exponent */ ((su_int)a & 0x007FFFFF); /* mantissa */ return fb.f; } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_l2f(di_int a) { return __floatdisf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatsidf.c ================================================ //===-- lib/floatsidf.c - integer -> double-precision conversion --*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements integer to double-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatsidf(int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // All other cases begin by extracting the sign and absolute value of a rep_t sign = 0; if (a < 0) { sign = signBit; a = -a; } // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field and clear the implicit bit. Extra // cast to unsigned int is necessary to get the correct behavior for // the input INT_MIN. const int shift = significandBits - exponent; result = (rep_t)(unsigned int)a << shift ^ implicitBit; // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; // Insert the sign bit and return return fromRep(result | sign); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_i2d(int a) { return __floatsidf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatsisf.c ================================================ //===-- lib/floatsisf.c - integer -> single-precision conversion --*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements integer to single-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatsisf(int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // All other cases begin by extracting the sign and absolute value of a rep_t sign = 0; if (a < 0) { sign = signBit; a = -a; } // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field, rounding if it is a right-shift if (exponent <= significandBits) { const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; } else { const int shift = exponent - significandBits; result = (rep_t)a >> shift ^ implicitBit; rep_t round = (rep_t)a << (typeWidth - shift); if (round > signBit) result++; if (round == signBit) result += result & 1; } // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; // Insert the sign bit and return return fromRep(result | sign); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_i2f(int a) { return __floatsisf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatundidf.c ================================================ /* ===-- floatundidf.c - Implement __floatundidf ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __floatundidf for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ /* Returns: convert a to a double, rounding toward even. */ /* Assumption: double is a IEEE 64 bit floating point type * du_int is a 64 bit integral type */ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag * as a side-effect of this computation. */ COMPILER_RT_ABI double __floatundidf(du_int a) { static const double twop52 = 4503599627370496.0; // 0x1.0p52 static const double twop84 = 19342813113834066795298816.0; // 0x1.0p84 static const double twop84_plus_twop52 = 19342813118337666422669312.0; // 0x1.00000001p84 union { uint64_t x; double d; } high = { .d = twop84 }; union { uint64_t x; double d; } low = { .d = twop52 }; high.x |= a >> 32; low.x |= a & UINT64_C(0x00000000ffffffff); const double result = (high.d - twop84_plus_twop52) + low.d; return result; } #else /* Support for systems that don't have hardware floating-point; there are no flags to * set, and we don't want to code-gen to an unknown soft-float implementation. */ COMPILER_RT_ABI double __floatundidf(du_int a) { if (a == 0) return 0.0; const unsigned N = sizeof(du_int) * CHAR_BIT; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* exponent */ if (sd > DBL_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit DBL_MANT_DIG-1 bits to the right of 1 * Q = bit DBL_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case DBL_MANT_DIG + 1: a <<= 1; break; case DBL_MANT_DIG + 2: break; default: a = (a >> (sd - (DBL_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + DBL_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits */ if (a & ((du_int)1 << DBL_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to DBL_MANT_DIG bits */ } else { a <<= (DBL_MANT_DIG - sd); /* a is now rounded to DBL_MANT_DIG bits */ } double_bits fb; fb.u.s.high = ((e + 1023) << 20) | /* exponent */ ((su_int)(a >> 32) & 0x000FFFFF); /* mantissa-high */ fb.u.s.low = (su_int)a; /* mantissa-low */ return fb.f; } #endif #if defined(__ARM_EABI__) AEABI_RTABI double __aeabi_ul2d(du_int a) { return __floatundidf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatundisf.c ================================================ /*===-- floatundisf.c - Implement __floatundisf ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __floatundisf for the compiler_rt library. * *===----------------------------------------------------------------------=== */ /* Returns: convert a to a float, rounding toward even. */ /* Assumption: float is a IEEE 32 bit floating point type * du_int is a 64 bit integral type */ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ #include "int_lib.h" COMPILER_RT_ABI float __floatundisf(du_int a) { if (a == 0) return 0.0F; const unsigned N = sizeof(du_int) * CHAR_BIT; int sd = N - __builtin_clzll(a); /* number of significant digits */ int e = sd - 1; /* 8 exponent */ if (sd > FLT_MANT_DIG) { /* start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx * finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR * 12345678901234567890123456 * 1 = msb 1 bit * P = bit FLT_MANT_DIG-1 bits to the right of 1 * Q = bit FLT_MANT_DIG bits to the right of 1 * R = "or" of all bits to the right of Q */ switch (sd) { case FLT_MANT_DIG + 1: a <<= 1; break; case FLT_MANT_DIG + 2: break; default: a = (a >> (sd - (FLT_MANT_DIG + 2))) | ((a & ((du_int)(-1) >> ((N + FLT_MANT_DIG + 2) - sd))) != 0); }; /* finish: */ a |= (a & 4) != 0; /* Or P into R */ ++a; /* round - this step may add a significant bit */ a >>= 2; /* dump Q and R */ /* a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits */ if (a & ((du_int)1 << FLT_MANT_DIG)) { a >>= 1; ++e; } /* a is now rounded to FLT_MANT_DIG bits */ } else { a <<= (FLT_MANT_DIG - sd); /* a is now rounded to FLT_MANT_DIG bits */ } float_bits fb; fb.u = ((e + 127) << 23) | /* exponent */ ((su_int)a & 0x007FFFFF); /* mantissa */ return fb.f; } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_ul2f(du_int a) { return __floatundisf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatunsidf.c ================================================ //===-- lib/floatunsidf.c - uint -> double-precision conversion ---*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements unsigned integer to double-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatunsidf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field and clear the implicit bit. const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; return fromRep(result); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ui2d(unsigned int a) { return __floatunsidf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/floatunsisf.c ================================================ //===-- lib/floatunsisf.c - uint -> single-precision conversion ---*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements unsigned integer to single-precision conversion for the // compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even // mode. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" #include "int_lib.h" COMPILER_RT_ABI fp_t __floatunsisf(unsigned int a) { const int aWidth = sizeof a * CHAR_BIT; // Handle zero as a special case to protect clz if (a == 0) return fromRep(0); // Exponent of (fp_t)a is the width of abs(a). const int exponent = (aWidth - 1) - __builtin_clz(a); rep_t result; // Shift a into the significand field, rounding if it is a right-shift if (exponent <= significandBits) { const int shift = significandBits - exponent; result = (rep_t)a << shift ^ implicitBit; } else { const int shift = exponent - significandBits; result = (rep_t)a >> shift ^ implicitBit; rep_t round = (rep_t)a << (typeWidth - shift); if (round > signBit) result++; if (round == signBit) result += result & 1; } // Insert the exponent result += (rep_t)(exponent + exponentBias) << significandBits; return fromRep(result); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_ui2f(unsigned int a) { return __floatunsisf(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_add_impl.inc ================================================ //===----- lib/fp_add_impl.inc - floaing point addition -----------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements soft-float addition with the IEEE-754 default rounding // (to nearest, ties to even). // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fp_t __addXf3__(fp_t a, fp_t b) { rep_t aRep = toRep(a); rep_t bRep = toRep(b); const rep_t aAbs = aRep & absMask; const rep_t bAbs = bRep & absMask; // Detect if a or b is zero, infinity, or NaN. if (aAbs - REP_C(1) >= infRep - REP_C(1) || bAbs - REP_C(1) >= infRep - REP_C(1)) { // NaN + anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything + NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // +/-infinity + -/+infinity = qNaN if ((toRep(a) ^ toRep(b)) == signBit) return fromRep(qnanRep); // +/-infinity + anything remaining = +/- infinity else return a; } // anything remaining + +/-infinity = +/-infinity if (bAbs == infRep) return b; // zero + anything = anything if (!aAbs) { // but we need to get the sign right for zero + zero if (!bAbs) return fromRep(toRep(a) & toRep(b)); else return b; } // anything + zero = anything if (!bAbs) return a; } // Swap a and b if necessary so that a has the larger absolute value. if (bAbs > aAbs) { const rep_t temp = aRep; aRep = bRep; bRep = temp; } // Extract the exponent and significand from the (possibly swapped) a and b. int aExponent = aRep >> significandBits & maxExponent; int bExponent = bRep >> significandBits & maxExponent; rep_t aSignificand = aRep & significandMask; rep_t bSignificand = bRep & significandMask; // Normalize any denormals, and adjust the exponent accordingly. if (aExponent == 0) aExponent = normalize(&aSignificand); if (bExponent == 0) bExponent = normalize(&bSignificand); // The sign of the result is the sign of the larger operand, a. If they // have opposite signs, we are performing a subtraction; otherwise addition. const rep_t resultSign = aRep & signBit; const bool subtraction = (aRep ^ bRep) & signBit; // Shift the significands to give us round, guard and sticky, and or in the // implicit significand bit. (If we fell through from the denormal path it // was already set by normalize( ), but setting it twice won't hurt // anything.) aSignificand = (aSignificand | implicitBit) << 3; bSignificand = (bSignificand | implicitBit) << 3; // Shift the significand of b by the difference in exponents, with a sticky // bottom bit to get rounding correct. const unsigned int align = aExponent - bExponent; if (align) { if (align < typeWidth) { const bool sticky = bSignificand << (typeWidth - align); bSignificand = bSignificand >> align | sticky; } else { bSignificand = 1; // sticky; b is known to be non-zero. } } if (subtraction) { aSignificand -= bSignificand; // If a == -b, return +zero. if (aSignificand == 0) return fromRep(0); // If partial cancellation occured, we need to left-shift the result // and adjust the exponent: if (aSignificand < implicitBit << 3) { const int shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3); aSignificand <<= shift; aExponent -= shift; } } else /* addition */ { aSignificand += bSignificand; // If the addition carried up, we need to right-shift the result and // adjust the exponent: if (aSignificand & implicitBit << 4) { const bool sticky = aSignificand & 1; aSignificand = aSignificand >> 1 | sticky; aExponent += 1; } } // If we have overflowed the type, return +/- infinity: if (aExponent >= maxExponent) return fromRep(infRep | resultSign); if (aExponent <= 0) { // Result is denormal before rounding; the exponent is zero and we // need to shift the significand. const int shift = 1 - aExponent; const bool sticky = aSignificand << (typeWidth - shift); aSignificand = aSignificand >> shift | sticky; aExponent = 0; } // Low three bits are round, guard, and sticky. const int roundGuardSticky = aSignificand & 0x7; // Shift the significand into place, and mask off the implicit bit. rep_t result = aSignificand >> 3 & significandMask; // Insert the exponent and sign. result |= (rep_t)aExponent << significandBits; result |= resultSign; // Final rounding. The result may overflow to infinity, but that is the // correct result in that case. if (roundGuardSticky > 0x4) result++; if (roundGuardSticky == 0x4) result += result & 1; return fromRep(result); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_extend.h ================================================ //===-lib/fp_extend.h - low precision -> high precision conversion -*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // Set source and destination setting // //===----------------------------------------------------------------------===// #ifndef FP_EXTEND_HEADER #define FP_EXTEND_HEADER #include "int_lib.h" #if defined SRC_SINGLE typedef float src_t; typedef uint32_t src_rep_t; #define SRC_REP_C UINT32_C static const int srcSigBits = 23; #define src_rep_t_clz __builtin_clz #elif defined SRC_DOUBLE typedef double src_t; typedef uint64_t src_rep_t; #define SRC_REP_C UINT64_C static const int srcSigBits = 52; static __inline int src_rep_t_clz(src_rep_t a) { #if defined __LP64__ return __builtin_clzl(a); #else if (a & REP_C(0xffffffff00000000)) return __builtin_clz(a >> 32); else return 32 + __builtin_clz(a & REP_C(0xffffffff)); #endif } #elif defined SRC_HALF typedef uint16_t src_t; typedef uint16_t src_rep_t; #define SRC_REP_C UINT16_C static const int srcSigBits = 10; #define src_rep_t_clz __builtin_clz #else #error Source should be half, single, or double precision! #endif // end source precision #if defined DST_SINGLE typedef float dst_t; typedef uint32_t dst_rep_t; #define DST_REP_C UINT32_C static const int dstSigBits = 23; #elif defined DST_DOUBLE typedef double dst_t; typedef uint64_t dst_rep_t; #define DST_REP_C UINT64_C static const int dstSigBits = 52; #elif defined DST_QUAD typedef long double dst_t; typedef __uint128_t dst_rep_t; #define DST_REP_C (__uint128_t) static const int dstSigBits = 112; #else #error Destination should be single, double, or quad precision! #endif // end destination precision // End of specialization parameters. Two helper routines for conversion to and // from the representation of floating-point data as integer values follow. static __inline src_rep_t srcToRep(src_t x) { const union { src_t f; src_rep_t i; } rep = { .f = x }; return rep.i; } static __inline dst_t dstFromRep(dst_rep_t x) { const union { dst_t f; dst_rep_t i; } rep = { .i = x }; return rep.f; } // End helper routines. Conversion implementation follows. #endif // FP_EXTEND_HEADER ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_extend_impl.inc ================================================ //=-lib/fp_extend_impl.inc - low precision -> high precision conversion -*-- -// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a fairly generic conversion from a narrower to a wider // IEEE-754 floating-point type. The constants and types defined following the // includes below parameterize the conversion. // // It does not support types that don't use the usual IEEE-754 interchange // formats; specifically, some work would be needed to adapt it to // (for example) the Intel 80-bit format or PowerPC double-double format. // // Note please, however, that this implementation is only intended to support // *widening* operations; if you need to convert to a *narrower* floating-point // type (e.g. double -> float), then this routine will not do what you want it // to. // // It also requires that integer types at least as large as both formats // are available on the target platform; this may pose a problem when trying // to add support for quad on some 32-bit systems, for example. You also may // run into trouble finding an appropriate CLZ function for wide source types; // you will likely need to roll your own on some platforms. // // Finally, the following assumptions are made: // // 1. floating-point types and integer types have the same endianness on the // target platform // // 2. quiet NaNs, if supported, are indicated by the leading bit of the // significand field being set // //===----------------------------------------------------------------------===// #include "fp_extend.h" static __inline dst_t __extendXfYf2__(src_t a) { // Various constants whose values follow from the type parameters. // Any reasonable optimizer will fold and propagate all of these. const int srcBits = sizeof(src_t)*CHAR_BIT; const int srcExpBits = srcBits - srcSigBits - 1; const int srcInfExp = (1 << srcExpBits) - 1; const int srcExpBias = srcInfExp >> 1; const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); const src_rep_t srcAbsMask = srcSignMask - 1; const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); const src_rep_t srcNaNCode = srcQNaN - 1; const int dstBits = sizeof(dst_t)*CHAR_BIT; const int dstExpBits = dstBits - dstSigBits - 1; const int dstInfExp = (1 << dstExpBits) - 1; const int dstExpBias = dstInfExp >> 1; const dst_rep_t dstMinNormal = DST_REP_C(1) << dstSigBits; // Break a into a sign and representation of the absolute value const src_rep_t aRep = srcToRep(a); const src_rep_t aAbs = aRep & srcAbsMask; const src_rep_t sign = aRep & srcSignMask; dst_rep_t absResult; // If sizeof(src_rep_t) < sizeof(int), the subtraction result is promoted // to (signed) int. To avoid that, explicitly cast to src_rep_t. if ((src_rep_t)(aAbs - srcMinNormal) < srcInfinity - srcMinNormal) { // a is a normal number. // Extend to the destination type by shifting the significand and // exponent into the proper position and rebiasing the exponent. absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits); absResult += (dst_rep_t)(dstExpBias - srcExpBias) << dstSigBits; } else if (aAbs >= srcInfinity) { // a is NaN or infinity. // Conjure the result by beginning with infinity, then setting the qNaN // bit (if needed) and right-aligning the rest of the trailing NaN // payload field. absResult = (dst_rep_t)dstInfExp << dstSigBits; absResult |= (dst_rep_t)(aAbs & srcQNaN) << (dstSigBits - srcSigBits); absResult |= (dst_rep_t)(aAbs & srcNaNCode) << (dstSigBits - srcSigBits); } else if (aAbs) { // a is denormal. // renormalize the significand and clear the leading bit, then insert // the correct adjusted exponent in the destination type. const int scale = src_rep_t_clz(aAbs) - src_rep_t_clz(srcMinNormal); absResult = (dst_rep_t)aAbs << (dstSigBits - srcSigBits + scale); absResult ^= dstMinNormal; const int resultExponent = dstExpBias - srcExpBias - scale + 1; absResult |= (dst_rep_t)resultExponent << dstSigBits; } else { // a is zero. absResult = 0; } // Apply the signbit to (dst_t)abs(a). const dst_rep_t result = absResult | (dst_rep_t)sign << (dstBits - srcBits); return dstFromRep(result); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_fixint_impl.inc ================================================ //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements float to integer conversion for the // compiler-rt library. // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fixint_t __fixint(fp_t a) { const fixint_t fixint_max = (fixint_t)((~(fixuint_t)0) / 2); const fixint_t fixint_min = -fixint_max - 1; // Break a into sign, exponent, significand const rep_t aRep = toRep(a); const rep_t aAbs = aRep & absMask; const fixint_t sign = aRep & signBit ? -1 : 1; const int exponent = (aAbs >> significandBits) - exponentBias; const rep_t significand = (aAbs & significandMask) | implicitBit; // If exponent is negative, the result is zero. if (exponent < 0) return 0; // If the value is too large for the integer type, saturate. if ((unsigned)exponent >= sizeof(fixint_t) * CHAR_BIT) return sign == 1 ? fixint_max : fixint_min; // If 0 <= exponent < significandBits, right shift to get the result. // Otherwise, shift left. if (exponent < significandBits) return sign * (significand >> (significandBits - exponent)); else return sign * ((fixint_t)significand << (exponent - significandBits)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_fixuint_impl.inc ================================================ //===-- lib/fixdfsi.c - Double-precision -> integer conversion ----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements float to unsigned integer conversion for the // compiler-rt library. // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fixuint_t __fixuint(fp_t a) { // Break a into sign, exponent, significand const rep_t aRep = toRep(a); const rep_t aAbs = aRep & absMask; const int sign = aRep & signBit ? -1 : 1; const int exponent = (aAbs >> significandBits) - exponentBias; const rep_t significand = (aAbs & significandMask) | implicitBit; // If either the value or the exponent is negative, the result is zero. if (sign == -1 || exponent < 0) return 0; // If the value is too large for the integer type, saturate. if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT) return ~(fixuint_t)0; // If 0 <= exponent < significandBits, right shift to get the result. // Otherwise, shift left. if (exponent < significandBits) return significand >> (significandBits - exponent); else return (fixuint_t)significand << (exponent - significandBits); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_lib.h ================================================ //===-- lib/fp_lib.h - Floating-point utilities -------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a configuration header for soft-float routines in compiler-rt. // This file does not provide any part of the compiler-rt interface, but defines // many useful constants and utility routines that are used in the // implementation of the soft-float routines in compiler-rt. // // Assumes that float, double and long double correspond to the IEEE-754 // binary32, binary64 and binary 128 types, respectively, and that integer // endianness matches floating point endianness on the target platform. // //===----------------------------------------------------------------------===// #ifndef FP_LIB_HEADER #define FP_LIB_HEADER #include #include #include #include "int_lib.h" // x86_64 FreeBSD prior v9.3 define fixed-width types incorrectly in // 32-bit mode. #if defined(__FreeBSD__) && defined(__i386__) #include #if __FreeBSD_version < 903000 // v9.3 #define uint64_t unsigned long long #define int64_t long long #undef UINT64_C #define UINT64_C(c) (c##ULL) #endif #endif #if defined SINGLE_PRECISION typedef uint32_t rep_t; typedef int32_t srep_t; typedef float fp_t; #define REP_C UINT32_C #define significandBits 23 static __inline int rep_clz(rep_t a) { return __builtin_clz(a); } // 32x32 --> 64 bit multiply static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { const uint64_t product = (uint64_t)a * b; *hi = product >> 32; *lo = product; } COMPILER_RT_ABI fp_t __addsf3(fp_t a, fp_t b); #elif defined DOUBLE_PRECISION typedef uint64_t rep_t; typedef int64_t srep_t; typedef double fp_t; #define REP_C UINT64_C #define significandBits 52 static __inline int rep_clz(rep_t a) { #if defined __LP64__ return __builtin_clzl(a); #else if (a & REP_C(0xffffffff00000000)) return __builtin_clz(a >> 32); else return 32 + __builtin_clz(a & REP_C(0xffffffff)); #endif } #define loWord(a) (a & 0xffffffffU) #define hiWord(a) (a >> 32) // 64x64 -> 128 wide multiply for platforms that don't have such an operation; // many 64-bit platforms have this operation, but they tend to have hardware // floating-point, so we don't bother with a special case for them here. static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { // Each of the component 32x32 -> 64 products const uint64_t plolo = loWord(a) * loWord(b); const uint64_t plohi = loWord(a) * hiWord(b); const uint64_t philo = hiWord(a) * loWord(b); const uint64_t phihi = hiWord(a) * hiWord(b); // Sum terms that contribute to lo in a way that allows us to get the carry const uint64_t r0 = loWord(plolo); const uint64_t r1 = hiWord(plolo) + loWord(plohi) + loWord(philo); *lo = r0 + (r1 << 32); // Sum terms contributing to hi with the carry from lo *hi = hiWord(plohi) + hiWord(philo) + hiWord(r1) + phihi; } #undef loWord #undef hiWord COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b); #elif defined QUAD_PRECISION #if __LDBL_MANT_DIG__ == 113 #define CRT_LDBL_128BIT typedef __uint128_t rep_t; typedef __int128_t srep_t; typedef long double fp_t; #define REP_C (__uint128_t) // Note: Since there is no explicit way to tell compiler the constant is a // 128-bit integer, we let the constant be casted to 128-bit integer #define significandBits 112 static __inline int rep_clz(rep_t a) { const union { __uint128_t ll; #if _YUGA_BIG_ENDIAN struct { uint64_t high, low; } s; #else struct { uint64_t low, high; } s; #endif } uu = { .ll = a }; uint64_t word; uint64_t add; if (uu.s.high) { word = uu.s.high; add = 0; } else { word = uu.s.low; add = 64; } return __builtin_clzll(word) + add; } #define Word_LoMask UINT64_C(0x00000000ffffffff) #define Word_HiMask UINT64_C(0xffffffff00000000) #define Word_FullMask UINT64_C(0xffffffffffffffff) #define Word_1(a) (uint64_t)((a >> 96) & Word_LoMask) #define Word_2(a) (uint64_t)((a >> 64) & Word_LoMask) #define Word_3(a) (uint64_t)((a >> 32) & Word_LoMask) #define Word_4(a) (uint64_t)(a & Word_LoMask) // 128x128 -> 256 wide multiply for platforms that don't have such an operation; // many 64-bit platforms have this operation, but they tend to have hardware // floating-point, so we don't bother with a special case for them here. static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { const uint64_t product11 = Word_1(a) * Word_1(b); const uint64_t product12 = Word_1(a) * Word_2(b); const uint64_t product13 = Word_1(a) * Word_3(b); const uint64_t product14 = Word_1(a) * Word_4(b); const uint64_t product21 = Word_2(a) * Word_1(b); const uint64_t product22 = Word_2(a) * Word_2(b); const uint64_t product23 = Word_2(a) * Word_3(b); const uint64_t product24 = Word_2(a) * Word_4(b); const uint64_t product31 = Word_3(a) * Word_1(b); const uint64_t product32 = Word_3(a) * Word_2(b); const uint64_t product33 = Word_3(a) * Word_3(b); const uint64_t product34 = Word_3(a) * Word_4(b); const uint64_t product41 = Word_4(a) * Word_1(b); const uint64_t product42 = Word_4(a) * Word_2(b); const uint64_t product43 = Word_4(a) * Word_3(b); const uint64_t product44 = Word_4(a) * Word_4(b); const __uint128_t sum0 = (__uint128_t)product44; const __uint128_t sum1 = (__uint128_t)product34 + (__uint128_t)product43; const __uint128_t sum2 = (__uint128_t)product24 + (__uint128_t)product33 + (__uint128_t)product42; const __uint128_t sum3 = (__uint128_t)product14 + (__uint128_t)product23 + (__uint128_t)product32 + (__uint128_t)product41; const __uint128_t sum4 = (__uint128_t)product13 + (__uint128_t)product22 + (__uint128_t)product31; const __uint128_t sum5 = (__uint128_t)product12 + (__uint128_t)product21; const __uint128_t sum6 = (__uint128_t)product11; const __uint128_t r0 = (sum0 & Word_FullMask) + ((sum1 & Word_LoMask) << 32); const __uint128_t r1 = (sum0 >> 64) + ((sum1 >> 32) & Word_FullMask) + (sum2 & Word_FullMask) + ((sum3 << 32) & Word_HiMask); *lo = r0 + (r1 << 64); *hi = (r1 >> 64) + (sum1 >> 96) + (sum2 >> 64) + (sum3 >> 32) + sum4 + (sum5 << 32) + (sum6 << 64); } #undef Word_1 #undef Word_2 #undef Word_3 #undef Word_4 #undef Word_HiMask #undef Word_LoMask #undef Word_FullMask #endif // __LDBL_MANT_DIG__ == 113 #else #error SINGLE_PRECISION, DOUBLE_PRECISION or QUAD_PRECISION must be defined. #endif #if defined(SINGLE_PRECISION) || defined(DOUBLE_PRECISION) || defined(CRT_LDBL_128BIT) #define typeWidth (sizeof(rep_t) * CHAR_BIT) #define exponentBits (typeWidth - significandBits - 1) #define maxExponent ((1 << exponentBits) - 1) #define exponentBias (maxExponent >> 1) #define implicitBit (REP_C(1) << significandBits) #define significandMask (implicitBit - 1U) #define signBit (REP_C(1) << (significandBits + exponentBits)) #define absMask (signBit - 1U) #define exponentMask (absMask ^ significandMask) #define oneRep ((rep_t)exponentBias << significandBits) #define infRep exponentMask #define quietBit (implicitBit >> 1) #define qnanRep (exponentMask | quietBit) static __inline rep_t toRep(fp_t x) { const union { fp_t f; rep_t i; } rep = { .f = x }; return rep.i; } static __inline fp_t fromRep(rep_t x) { const union { fp_t f; rep_t i; } rep = { .i = x }; return rep.f; } static __inline int normalize(rep_t *significand) { const int shift = rep_clz(*significand) - rep_clz(implicitBit); *significand <<= shift; return 1 - shift; } static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) { *hi = *hi << count | *lo >> (typeWidth - count); *lo = *lo << count; } static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) { if (count < typeWidth) { const bool sticky = *lo << (typeWidth - count); *lo = *hi << (typeWidth - count) | *lo >> count | sticky; *hi = *hi >> count; } else if (count < 2 * typeWidth) { const bool sticky = *hi << (2 * typeWidth - count) | *lo; *lo = *hi >> (count - typeWidth) | sticky; *hi = 0; } else { const bool sticky = *hi | *lo; *lo = sticky; *hi = 0; } } #endif #endif // FP_LIB_HEADER ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_mul_impl.inc ================================================ //===---- lib/fp_mul_impl.inc - floating point multiplication -----*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements soft-float multiplication with the IEEE-754 default // rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #include "fp_lib.h" static __inline fp_t __mulXf3__(fp_t a, fp_t b) { const unsigned int aExponent = toRep(a) >> significandBits & maxExponent; const unsigned int bExponent = toRep(b) >> significandBits & maxExponent; const rep_t productSign = (toRep(a) ^ toRep(b)) & signBit; rep_t aSignificand = toRep(a) & significandMask; rep_t bSignificand = toRep(b) & significandMask; int scale = 0; // Detect if a or b is zero, denormal, infinity, or NaN. if (aExponent-1U >= maxExponent-1U || bExponent-1U >= maxExponent-1U) { const rep_t aAbs = toRep(a) & absMask; const rep_t bAbs = toRep(b) & absMask; // NaN * anything = qNaN if (aAbs > infRep) return fromRep(toRep(a) | quietBit); // anything * NaN = qNaN if (bAbs > infRep) return fromRep(toRep(b) | quietBit); if (aAbs == infRep) { // infinity * non-zero = +/- infinity if (bAbs) return fromRep(aAbs | productSign); // infinity * zero = NaN else return fromRep(qnanRep); } if (bAbs == infRep) { //? non-zero * infinity = +/- infinity if (aAbs) return fromRep(bAbs | productSign); // zero * infinity = NaN else return fromRep(qnanRep); } // zero * anything = +/- zero if (!aAbs) return fromRep(productSign); // anything * zero = +/- zero if (!bAbs) return fromRep(productSign); // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. if (aAbs < implicitBit) scale += normalize(&aSignificand); if (bAbs < implicitBit) scale += normalize(&bSignificand); } // Or in the implicit significand bit. (If we fell through from the // denormal path it was already set by normalize( ), but setting it twice // won't hurt anything.) aSignificand |= implicitBit; bSignificand |= implicitBit; // Get the significand of a*b. Before multiplying the significands, shift // one of them left to left-align it in the field. Thus, the product will // have (exponentBits + 2) integral digits, all but two of which must be // zero. Normalizing this result is just a conditional left-shift by one // and bumping the exponent accordingly. rep_t productHi, productLo; wideMultiply(aSignificand, bSignificand << exponentBits, &productHi, &productLo); int productExponent = aExponent + bExponent - exponentBias + scale; // Normalize the significand, adjust exponent if needed. if (productHi & implicitBit) productExponent++; else wideLeftShift(&productHi, &productLo, 1); // If we have overflowed the type, return +/- infinity. if (productExponent >= maxExponent) return fromRep(infRep | productSign); if (productExponent <= 0) { // Result is denormal before rounding // // If the result is so small that it just underflows to zero, return // a zero of the appropriate sign. Mathematically there is no need to // handle this case separately, but we make it a special case to // simplify the shift logic. const unsigned int shift = REP_C(1) - (unsigned int)productExponent; if (shift >= typeWidth) return fromRep(productSign); // Otherwise, shift the significand of the result so that the round // bit is the high bit of productLo. wideRightShiftWithSticky(&productHi, &productLo, shift); } else { // Result is normal before rounding; insert the exponent. productHi &= significandMask; productHi |= (rep_t)productExponent << significandBits; } // Insert the sign of the result: productHi |= productSign; // Final rounding. The final result may overflow to infinity, or underflow // to zero, but those are the correct results in those cases. We use the // default IEEE-754 round-to-nearest, ties-to-even rounding mode. if (productLo > signBit) productHi++; if (productLo == signBit) productHi += productHi & 1; return fromRep(productHi); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_trunc.h ================================================ //=== lib/fp_trunc.h - high precision -> low precision conversion *- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // Set source and destination precision setting // //===----------------------------------------------------------------------===// #ifndef FP_TRUNC_HEADER #define FP_TRUNC_HEADER #include "int_lib.h" #if defined SRC_SINGLE typedef float src_t; typedef uint32_t src_rep_t; #define SRC_REP_C UINT32_C static const int srcSigBits = 23; #elif defined SRC_DOUBLE typedef double src_t; typedef uint64_t src_rep_t; #define SRC_REP_C UINT64_C static const int srcSigBits = 52; #elif defined SRC_QUAD typedef long double src_t; typedef __uint128_t src_rep_t; #define SRC_REP_C (__uint128_t) static const int srcSigBits = 112; #else #error Source should be double precision or quad precision! #endif // end source precision #if defined DST_DOUBLE typedef double dst_t; typedef uint64_t dst_rep_t; #define DST_REP_C UINT64_C static const int dstSigBits = 52; #elif defined DST_SINGLE typedef float dst_t; typedef uint32_t dst_rep_t; #define DST_REP_C UINT32_C static const int dstSigBits = 23; #elif defined DST_HALF typedef uint16_t dst_t; typedef uint16_t dst_rep_t; #define DST_REP_C UINT16_C static const int dstSigBits = 10; #else #error Destination should be single precision or double precision! #endif // end destination precision // End of specialization parameters. Two helper routines for conversion to and // from the representation of floating-point data as integer values follow. static __inline src_rep_t srcToRep(src_t x) { const union { src_t f; src_rep_t i; } rep = { .f = x }; return rep.i; } static __inline dst_t dstFromRep(dst_rep_t x) { const union { dst_t f; dst_rep_t i; } rep = { .i = x }; return rep.f; } #endif // FP_TRUNC_HEADER ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fp_trunc_impl.inc ================================================ //= lib/fp_trunc_impl.inc - high precision -> low precision conversion *-*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements a fairly generic conversion from a wider to a narrower // IEEE-754 floating-point type in the default (round to nearest, ties to even) // rounding mode. The constants and types defined following the includes below // parameterize the conversion. // // This routine can be trivially adapted to support conversions to // half-precision or from quad-precision. It does not support types that don't // use the usual IEEE-754 interchange formats; specifically, some work would be // needed to adapt it to (for example) the Intel 80-bit format or PowerPC // double-double format. // // Note please, however, that this implementation is only intended to support // *narrowing* operations; if you need to convert to a *wider* floating-point // type (e.g. float -> double), then this routine will not do what you want it // to. // // It also requires that integer types at least as large as both formats // are available on the target platform; this may pose a problem when trying // to add support for quad on some 32-bit systems, for example. // // Finally, the following assumptions are made: // // 1. floating-point types and integer types have the same endianness on the // target platform // // 2. quiet NaNs, if supported, are indicated by the leading bit of the // significand field being set // //===----------------------------------------------------------------------===// #include "fp_trunc.h" static __inline dst_t __truncXfYf2__(src_t a) { // Various constants whose values follow from the type parameters. // Any reasonable optimizer will fold and propagate all of these. const int srcBits = sizeof(src_t)*CHAR_BIT; const int srcExpBits = srcBits - srcSigBits - 1; const int srcInfExp = (1 << srcExpBits) - 1; const int srcExpBias = srcInfExp >> 1; const src_rep_t srcMinNormal = SRC_REP_C(1) << srcSigBits; const src_rep_t srcSignificandMask = srcMinNormal - 1; const src_rep_t srcInfinity = (src_rep_t)srcInfExp << srcSigBits; const src_rep_t srcSignMask = SRC_REP_C(1) << (srcSigBits + srcExpBits); const src_rep_t srcAbsMask = srcSignMask - 1; const src_rep_t roundMask = (SRC_REP_C(1) << (srcSigBits - dstSigBits)) - 1; const src_rep_t halfway = SRC_REP_C(1) << (srcSigBits - dstSigBits - 1); const src_rep_t srcQNaN = SRC_REP_C(1) << (srcSigBits - 1); const src_rep_t srcNaNCode = srcQNaN - 1; const int dstBits = sizeof(dst_t)*CHAR_BIT; const int dstExpBits = dstBits - dstSigBits - 1; const int dstInfExp = (1 << dstExpBits) - 1; const int dstExpBias = dstInfExp >> 1; const int underflowExponent = srcExpBias + 1 - dstExpBias; const int overflowExponent = srcExpBias + dstInfExp - dstExpBias; const src_rep_t underflow = (src_rep_t)underflowExponent << srcSigBits; const src_rep_t overflow = (src_rep_t)overflowExponent << srcSigBits; const dst_rep_t dstQNaN = DST_REP_C(1) << (dstSigBits - 1); const dst_rep_t dstNaNCode = dstQNaN - 1; // Break a into a sign and representation of the absolute value const src_rep_t aRep = srcToRep(a); const src_rep_t aAbs = aRep & srcAbsMask; const src_rep_t sign = aRep & srcSignMask; dst_rep_t absResult; if (aAbs - underflow < aAbs - overflow) { // The exponent of a is within the range of normal numbers in the // destination format. We can convert by simply right-shifting with // rounding and adjusting the exponent. absResult = aAbs >> (srcSigBits - dstSigBits); absResult -= (dst_rep_t)(srcExpBias - dstExpBias) << dstSigBits; const src_rep_t roundBits = aAbs & roundMask; // Round to nearest if (roundBits > halfway) absResult++; // Ties to even else if (roundBits == halfway) absResult += absResult & 1; } else if (aAbs > srcInfinity) { // a is NaN. // Conjure the result by beginning with infinity, setting the qNaN // bit and inserting the (truncated) trailing NaN field. absResult = (dst_rep_t)dstInfExp << dstSigBits; absResult |= dstQNaN; absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode; } else if (aAbs >= overflow) { // a overflows to infinity. absResult = (dst_rep_t)dstInfExp << dstSigBits; } else { // a underflows on conversion to the destination type or is an exact // zero. The result may be a denormal or zero. Extract the exponent // to get the shift amount for the denormalization. const int aExp = aAbs >> srcSigBits; const int shift = srcExpBias - dstExpBias - aExp + 1; const src_rep_t significand = (aRep & srcSignificandMask) | srcMinNormal; // Right shift by the denormalization amount with sticky. if (shift > srcSigBits) { absResult = 0; } else { const bool sticky = significand << (srcBits - shift); src_rep_t denormalizedSignificand = significand >> shift | sticky; absResult = denormalizedSignificand >> (srcSigBits - dstSigBits); const src_rep_t roundBits = denormalizedSignificand & roundMask; // Round to nearest if (roundBits > halfway) absResult++; // Ties to even else if (roundBits == halfway) absResult += absResult & 1; } } // Apply the signbit to (dst_t)abs(a). const dst_rep_t result = absResult | sign >> (srcBits - dstBits); return dstFromRep(result); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fsb_allocator.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include ATOMIC_BIT_INIT(__fsb_lock); // noinline, because part of grind tracked functions fsb_allocator_t __noinline fsb_alloc(unsigned int block_size, unsigned int nb_of_blocks) { if (block_size > 0xFFFFFFF8) { __asm__ volatile("fault " __STR(__FAULT_ALLOC_HEAP_FULL__)); unreachable(); } block_size = (block_size == 0) ? 8 : (block_size + 7) & ~7; unsigned int memory_space_to_allocate = block_size * nb_of_blocks + 4; void *memory = mem_alloc(memory_space_to_allocate); unsigned int first_block = (unsigned int)memory; for (unsigned int each_block = 0; each_block < nb_of_blocks - 1; ++each_block) { unsigned int next_block_address = (unsigned int)(memory + block_size); *((unsigned int *)memory) = next_block_address; memory = (void *)next_block_address; } *((unsigned int *)memory) = 0; memory += block_size; void *free_ptr = memory; *((unsigned int *)free_ptr) = first_block; return (fsb_allocator_t)free_ptr; } // noinline, because part of grind tracked functions void *__noinline fsb_get(fsb_allocator_t allocator) { void **result; ATOMIC_BIT_ACQUIRE(__fsb_lock); __asm__ volatile("lw %[res], %[alloc], 0" : [res] "=r"(result) : [alloc] "r"(allocator)); if (result == NULL) { ATOMIC_BIT_RELEASE(__fsb_lock); return NULL; } void *next = *result; __asm__ volatile("sw %[alloc], 0, %[res]" : : [res] "r"(next), [alloc] "r"(allocator)); ATOMIC_BIT_RELEASE(__fsb_lock); return (void *)result; } // noinline, because part of grind tracked functions void __noinline fsb_free(fsb_allocator_t allocator, void *ptr) { void *next_free; ATOMIC_BIT_ACQUIRE(__fsb_lock); __asm__ volatile("lw %[res], %[alloc], 0" : [res] "=r"(next_free) : [alloc] "r"(allocator)); *((void **)ptr) = next_free; __asm__ volatile("sw %[alloc], 0, %[res]" : : [res] "r"(ptr), [alloc] "r"(allocator)); ATOMIC_BIT_RELEASE(__fsb_lock); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/fsb_allocator.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_FBS_ALLOC_H #define DPUSYSCORE_FBS_ALLOC_H /** * @file fsb_allocator.h * @brief Provides a fixed-size block memory allocator. * * @internal When defining an allocator, the total memory needed will be allocated, using mem_alloc. * The allocator structure is a pointer to the next available block. In each free block, the first four bytes * store a pointer to the following free block, creating a linked list. To allocate a block, we just check * the free pointer, check the next free pointer and update the free pointer accordingly. To free a block, we * just check the free pointer, update it with the newly free block, and update the next pointer of this block * with the previous free pointer. * There is no protection to prevent invalid block to be added to the list. Moreover, the list being in the free * blocks, if there is some memory overflow from a block, the list might be corrupted and totally invalid. */ /** * @fn fsb_allocator_t * @brief A fixed-size block allocator. */ typedef void **fsb_allocator_t; /** * @fn fsb_alloc * @brief Allocate and initialize a fixed-size block allocator. * * @param block_size the size of the blocks allocated (will be realigned on 8 bytes, with a minimum of 8 bytes) * @param nb_of_blocks the number of blocks allocated * @throws a fault if there is no memory left * @return The newly allocated and ready-to-use fixed-size block allocator. */ fsb_allocator_t fsb_alloc(unsigned int block_size, unsigned int nb_of_blocks); /** * @fn fsb_get * @brief Own a block of the specified fixed-size block allocator, in a runtime-safe way. * * @param allocator the allocator from which we take the block * @return A pointer to the owned block if one was available, NULL otherwise. */ void * fsb_get(fsb_allocator_t allocator); /** * @fn fsb_free * @brief Free a block of the specified fixed-size block allocator, in a runtime-safe way. * * @param allocator the allocator in which we put the block back in * @param ptr the pointer to the block to free */ void fsb_free(fsb_allocator_t allocator, void *ptr); #endif /* DPUSYSCORE_FBS_ALLOC_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/handshake.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include unsigned char __handshake_array[NR_THREADS] = { [0 ...(NR_THREADS - 1)] = __EMPTY_WAIT_QUEUE }; ATOMIC_BIT_INIT(__handshake)[NR_THREADS]; #define __acquire_handshake(off) __ATOMIC_BIT_ACQUIRE(off + (ATOMIC_BIT_GET(__handshake) - &__atomic_start_addr), 0) #define __release_handshake(off) __ATOMIC_BIT_RELEASE(off + (ATOMIC_BIT_GET(__handshake) - &__atomic_start_addr), 0) void handshake_notify(void) { thread_id_t tid = me(); unsigned char info; __acquire_handshake(tid); info = __handshake_array[tid]; if (unlikely(info == __EMPTY_WAIT_QUEUE)) { __handshake_array[tid] = tid; __release_handshake(tid); __stop(); } else { __resume(info, "0"); __handshake_array[tid] = __EMPTY_WAIT_QUEUE; __release_handshake(tid); } } int handshake_wait_for(unsigned int notifier) { thread_id_t tid = me(); unsigned char thread = (unsigned char)notifier; __acquire_handshake(thread); unsigned char info = __handshake_array[thread]; if (unlikely(info == __EMPTY_WAIT_QUEUE)) { __handshake_array[thread] = tid; __release_handshake(thread); __stop(); } else { if (unlikely(info != thread)) { errno = EALREADY; __release_handshake(thread); return EALREADY; } else { __resume(info, "0"); __handshake_array[thread] = __EMPTY_WAIT_QUEUE; } __release_handshake(thread); } return 0; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/handshake.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_HANDSHAKE_H #define DPUSYSCORE_HANDSHAKE_H /** * @file handshake.h * @brief Synchronization with handshakes. * * This synchronization mechanism allows to synchronize 2 tasklets. One tasklet will serve as a notifier * and will call handshake_notify() and the other as a customer and will call handshake_wait_for(notifier). * * @internal If the notifier called handshake_notify() before the customer, it will stop until some tasklet * calls handshake_wait_for(notifier). * If a tasklet called handshake_wait_for(notifier) before the notifier, it will stop until * the notifier calls handshake_notify(). If afterwards (still before the notifier calls * handshake_notify()) another tasklet attempts to call handshake_wait_for(notifier) with * the same tasklet in the parameter, the function will do nothing and will return the number * of error and set the errno to the corresponding error number. */ #include /** * @fn handshake_notify * @brief Notifies a tasklet waiting for the notifier. * * The invoking tasklet is suspended until another tasklet calls handshake_wait_for(notifier). * When this condition is reached, the function resumes the waiting tasklet. */ void handshake_notify(void); /** * @fn handshake_wait_for * @brief Waits for the notifier tasklet * * The invoking tasklet is suspended until the notifier tasklet (indicated in the parameter) sends a * notification to tell the invoking tasklet that it can go ahead. * * Beware that if the notifier tasklet and the invoking tasklet are the same, the tasklet will be suspended with no * easy way to wake it up. The user should check this case itself if it is something that their program allows. * * If the number of the notifier is not a defined tasklet, the function behavior is undefined. If some other tasklet has * already called handshake_wait_for() with the same notifier in the parameter and that the notifier has not yet called * handshake_notify(), the function will do nothing and simply return EALREADY. * * In both cases the errno will be set to the corresponding error number. * * @param notifier a number to wait the notification from. It must be a defined tasklet. * @return 0 if no error was detected, EALREADY if a corresponding error was detected. */ int handshake_wait_for(sysname_t notifier); #endif /* DPUSYSCORE_HANDSHAKE_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_endianness.h ================================================ /* ===-- int_endianness.h - configuration header for compiler-rt ------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== */ #ifndef INT_ENDIANNESS_H #define INT_ENDIANNESS_H #if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && defined(__ORDER_LITTLE_ENDIAN__) /* Clang and GCC provide built-in endianness definitions. */ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* __BYTE_ORDER__ */ #else /* Compilers other than Clang or GCC. */ #if defined(__SVR4) && defined(__sun) #include #if defined(_BIG_ENDIAN) #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif defined(_LITTLE_ENDIAN) #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #else /* !_LITTLE_ENDIAN */ #error "unknown endianness" #endif /* !_LITTLE_ENDIAN */ #endif /* Solaris and AuroraUX. */ /* .. */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__minix) #include #if _BYTE_ORDER == _BIG_ENDIAN #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif _BYTE_ORDER == _LITTLE_ENDIAN #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* _BYTE_ORDER */ #endif /* *BSD */ #if defined(__OpenBSD__) || defined(__Bitrig__) #include #if _BYTE_ORDER == _BIG_ENDIAN #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #elif _BYTE_ORDER == _LITTLE_ENDIAN #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* _BYTE_ORDER */ #endif /* OpenBSD and Bitrig. */ /* .. */ /* Mac OSX has __BIG_ENDIAN__ or __LITTLE_ENDIAN__ automatically set by the * compiler (at least with GCC) */ #if defined(__APPLE__) || defined(__ellcc__) #ifdef __BIG_ENDIAN__ #if __BIG_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 0 #define _YUGA_BIG_ENDIAN 1 #endif #endif /* __BIG_ENDIAN__ */ #ifdef __LITTLE_ENDIAN__ #if __LITTLE_ENDIAN__ #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif #endif /* __LITTLE_ENDIAN__ */ #endif /* Mac OSX */ /* .. */ #if defined(_WIN32) #define _YUGA_LITTLE_ENDIAN 1 #define _YUGA_BIG_ENDIAN 0 #endif /* Windows */ #endif /* Clang or GCC. */ /* . */ #if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN) #error Unable to determine endian #endif /* Check we found an endianness correctly. */ #endif /* INT_ENDIANNESS_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_lib.h ================================================ /* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is a configuration header for compiler-rt. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== */ #ifndef INT_LIB_H #define INT_LIB_H /* Assumption: Signed integral is 2's complement. */ /* Assumption: Right shift of signed negative is arithmetic shift. */ /* Assumption: Endianness is little or big (not mixed). */ #if defined(__ELF__) #define FNALIAS(alias_name, original_name) void alias_name() __attribute__((alias(#original_name))) #else #define FNALIAS(alias, name) _Pragma("GCC error(\"alias unsupported on this file format\")") #endif /* ABI macro definitions */ #if __ARM_EABI__ #ifdef COMPILER_RT_ARMHF_TARGET #define COMPILER_RT_ABI #else #define COMPILER_RT_ABI __attribute__((__pcs__("aapcs"))) #endif #else #define COMPILER_RT_ABI #endif #define AEABI_RTABI __attribute__((__pcs__("aapcs"))) #ifdef _MSC_VER #define ALWAYS_INLINE __forceinline #define NOINLINE __declspec(noinline) #define NORETURN __declspec(noreturn) #define UNUSED #else #define ALWAYS_INLINE __attribute__((always_inline)) #define NOINLINE __attribute__((noinline)) #define NORETURN __attribute__((noreturn)) #define UNUSED __attribute__((unused)) #endif #if defined(__NetBSD__) && (defined(_KERNEL) || defined(_STANDALONE)) /* * Kernel and boot environment can't use normal headers, * so use the equivalent system headers. */ #include #include #include #else /* Include the standard compiler builtin headers we use functionality from. */ #include #include #include #include #endif /* Include the commonly used internal type definitions. */ #include "int_types.h" /* Include internal utility function declarations. */ #include "int_util.h" COMPILER_RT_ABI si_int __paritysi2(si_int a); COMPILER_RT_ABI si_int __paritydi2(di_int a); COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem); COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem); #ifdef CRT_HAS_128BIT COMPILER_RT_ABI si_int __clzti2(ti_int a); COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); #endif /* Definitions for builtins unavailable on MSVC */ #if defined(_MSC_VER) && !defined(__clang__) #include uint32_t __inline __builtin_ctz(uint32_t value) { unsigned long trailing_zero = 0; if (_BitScanForward(&trailing_zero, value)) return trailing_zero; return 32; } uint32_t __inline __builtin_clz(uint32_t value) { unsigned long leading_zero = 0; if (_BitScanReverse(&leading_zero, value)) return 31 - leading_zero; return 32; } #if defined(_M_ARM) || defined(_M_X64) uint32_t __inline __builtin_clzll(uint64_t value) { unsigned long leading_zero = 0; if (_BitScanReverse64(&leading_zero, value)) return 63 - leading_zero; return 64; } #else uint32_t __inline __builtin_clzll(uint64_t value) { if (value == 0) return 64; uint32_t msh = (uint32_t)(value >> 32); uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF); if (msh != 0) return __builtin_clz(msh); return 32 + __builtin_clz(lsh); } #endif #define __builtin_clzl __builtin_clzll #endif /* defined(_MSC_VER) && !defined(__clang__) */ #endif /* INT_LIB_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_math.h ================================================ /* ===-- int_math.h - internal math inlines ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===-----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines substitutes for the libm functions used in some of the * compiler-rt implementations, defined in such a way that there is not a direct * dependency on libm or math.h. Instead, we use the compiler builtin versions * where available. This reduces our dependencies on the system SDK by foisting * the responsibility onto the compiler. * * ===-----------------------------------------------------------------------=== */ #ifndef INT_MATH_H #define INT_MATH_H #ifndef __has_builtin #define __has_builtin(x) 0 #endif #if defined(_MSC_VER) && !defined(__clang__) #include #include #include #endif #if defined(_MSC_VER) && !defined(__clang__) #define CRT_INFINITY INFINITY #else #define CRT_INFINITY __builtin_huge_valf() #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_isfinite(x) _finite((x)) #define crt_isinf(x) !_finite((x)) #define crt_isnan(x) _isnan((x)) #else /* Define crt_isfinite in terms of the builtin if available, otherwise provide * an alternate version in terms of our other functions. This supports some * versions of GCC which didn't have __builtin_isfinite. */ #if __has_builtin(__builtin_isfinite) #define crt_isfinite(x) __builtin_isfinite((x)) #elif defined(__GNUC__) #define crt_isfinite(x) \ __extension__(({ \ __typeof((x)) x_ = (x); \ crt_isinf(x_) && crt_isnan(x_); \ })) #else #error "Do not know how to check for infinity" #endif /* __has_builtin(__builtin_isfinite) */ #define crt_isinf(x) __builtin_isinf((x)) #define crt_isnan(x) __builtin_isnan((x)) #endif /* _MSC_VER */ #if defined(_MSC_VER) && !defined(__clang__) #define crt_copysign(x, y) copysign((x), (y)) #define crt_copysignf(x, y) copysignf((x), (y)) #define crt_copysignl(x, y) copysignl((x), (y)) #else #define crt_copysign(x, y) __builtin_copysign((x), (y)) #define crt_copysignf(x, y) __builtin_copysignf((x), (y)) #define crt_copysignl(x, y) __builtin_copysignl((x), (y)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_fabs(x) fabs((x)) #define crt_fabsf(x) fabsf((x)) #define crt_fabsl(x) fabs((x)) #else #define crt_fabs(x) __builtin_fabs((x)) #define crt_fabsf(x) __builtin_fabsf((x)) #define crt_fabsl(x) __builtin_fabsl((x)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_fmax(x, y) __max((x), (y)) #define crt_fmaxf(x, y) __max((x), (y)) #define crt_fmaxl(x, y) __max((x), (y)) #else #define crt_fmax(x, y) __builtin_fmax((x), (y)) #define crt_fmaxf(x, y) __builtin_fmaxf((x), (y)) #define crt_fmaxl(x, y) __builtin_fmaxl((x), (y)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_logb(x) logb((x)) #define crt_logbf(x) logbf((x)) #define crt_logbl(x) logbl((x)) #else #define crt_logb(x) __builtin_logb((x)) #define crt_logbf(x) __builtin_logbf((x)) #define crt_logbl(x) __builtin_logbl((x)) #endif #if defined(_MSC_VER) && !defined(__clang__) #define crt_scalbn(x, y) scalbn((x), (y)) #define crt_scalbnf(x, y) scalbnf((x), (y)) #define crt_scalbnl(x, y) scalbnl((x), (y)) #else #define crt_scalbn(x, y) __builtin_scalbn((x), (y)) #define crt_scalbnf(x, y) __builtin_scalbnf((x), (y)) #define crt_scalbnl(x, y) __builtin_scalbnl((x), (y)) #endif #endif /* INT_MATH_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_types.h ================================================ /* ===-- int_lib.h - configuration header for compiler-rt -----------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines various standard types, most importantly a number of unions * used to access parts of larger types. * * ===----------------------------------------------------------------------=== */ #ifndef INT_TYPES_H #define INT_TYPES_H #include "int_endianness.h" /* si_int is defined in Linux sysroot's asm-generic/siginfo.h */ #ifdef si_int #undef si_int #endif typedef int si_int; typedef unsigned su_int; typedef long long di_int; typedef unsigned long long du_int; typedef union { di_int all; struct { #if _YUGA_LITTLE_ENDIAN su_int low; si_int high; #else si_int high; su_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } dwords; typedef union { du_int all; struct { #if _YUGA_LITTLE_ENDIAN su_int low; su_int high; #else su_int high; su_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } udwords; #if (defined(__LP64__) || defined(__wasm__) || defined(__mips64)) #define CRT_HAS_128BIT #endif #ifdef CRT_HAS_128BIT typedef int ti_int __attribute__((mode(TI))); typedef unsigned tu_int __attribute__((mode(TI))); typedef union { ti_int all; struct { #if _YUGA_LITTLE_ENDIAN du_int low; di_int high; #else di_int high; du_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } twords; typedef union { tu_int all; struct { #if _YUGA_LITTLE_ENDIAN du_int low; du_int high; #else du_int high; du_int low; #endif /* _YUGA_LITTLE_ENDIAN */ } s; } utwords; static __inline ti_int make_ti(di_int h, di_int l) { twords r; r.s.high = h; r.s.low = l; return r.all; } static __inline tu_int make_tu(du_int h, du_int l) { utwords r; r.s.high = h; r.s.low = l; return r.all; } #endif /* CRT_HAS_128BIT */ typedef union { su_int u; float f; } float_bits; typedef union { udwords u; double f; } double_bits; typedef struct { #if _YUGA_LITTLE_ENDIAN udwords low; udwords high; #else udwords high; udwords low; #endif /* _YUGA_LITTLE_ENDIAN */ } uqwords; typedef union { uqwords u; long double f; } long_double_bits; #if __STDC_VERSION__ >= 199901L typedef float _Complex Fcomplex; typedef double _Complex Dcomplex; typedef long double _Complex Lcomplex; #define COMPLEX_REAL(x) __real__(x) #define COMPLEX_IMAGINARY(x) __imag__(x) #else typedef struct { float real, imaginary; } Fcomplex; typedef struct { double real, imaginary; } Dcomplex; typedef struct { long double real, imaginary; } Lcomplex; #define COMPLEX_REAL(x) (x).real #define COMPLEX_IMAGINARY(x) (x).imaginary #endif #endif /* INT_TYPES_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_util.c ================================================ /* ===-- int_util.c - Implement internal utilities --------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #include "int_util.h" /* NOTE: The definitions in this file are declared weak because we clients to be * able to arbitrarily package individual functions into separate .a files. If * we did not declare these weak, some link situations might end up seeing * duplicate strong definitions of the same symbol. * * We can't use this solution for kernel use (which may not support weak), but * currently expect that when built for kernel use all the functionality is * packaged into a single library. */ #ifdef KERNEL_USE NORETURN extern void panic(const char *, ...); #ifndef _WIN32 __attribute__((visibility("hidden"))) #endif void compilerrt_abort_impl(const char *file, int line, const char *function) { panic("%s:%d: abort in %s", file, line, function); } #elif __APPLE__ /* from libSystem.dylib */ NORETURN extern void __assert_rtn(const char *func, const char *file, int line, const char *message); #ifndef _WIN32 __attribute__((weak)) __attribute__((visibility("hidden"))) #endif void compilerrt_abort_impl(const char *file, int line, const char *function) { __assert_rtn(function, file, line, "libcompiler_rt abort"); } #else /* Get the system definition of abort() */ #include #ifndef _WIN32 // JFR dirty patch // DPUCC doesn't like it either __attribute__((weak)) // DPUCC doesn't like it either __attribute__((visibility("hidden"))) // End of patch #endif void compilerrt_abort_impl(const char *file __attribute__((unused)), int line __attribute__((unused)), const char *function __attribute__((unused))) { abort(); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/int_util.h ================================================ /* ===-- int_util.h - internal utility functions ----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===-----------------------------------------------------------------------=== * * This file is not part of the interface of this library. * * This file defines non-inline utilities which are available for use in the * library. The function definitions themselves are all contained in int_util.c * which will always be compiled into any compiler-rt library. * * ===-----------------------------------------------------------------------=== */ #ifndef INT_UTIL_H #define INT_UTIL_H /** \brief Trigger a program abort (or panic for kernel code). */ #define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, __func__) NORETURN void compilerrt_abort_impl(const char *file, int line, const char *function); #define COMPILE_TIME_ASSERT(expr) COMPILE_TIME_ASSERT1(expr, __COUNTER__) #define COMPILE_TIME_ASSERT1(expr, cnt) COMPILE_TIME_ASSERT2(expr, cnt) #define COMPILE_TIME_ASSERT2(expr, cnt) typedef char ct_assert_##cnt[(expr) ? 1 : -1] UNUSED #endif /* INT_UTIL_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/listener.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include extern bool fetch_request(uint32_t fifo_info, uint32_t *request, uint32_t request_size); extern bool fifo_is_full(uint32_t fifo_info, uint32_t request_size); extern void fifo_produce(uint32_t fifo_info, uint32_t *request, uint32_t request_size); static inline uint32_t fifo_sys_fetch_info(uint32_t fid) { extern uint32_t __sys_fifo_sys_table; return (&__sys_fifo_sys_table)[fid]; } static inline uint32_t fifo_fetch_info(sysname_t recipient) { extern uint32_t __sys_fifo_table_ptr; return *((uint32_t *)((&__sys_fifo_table_ptr)[recipient] & 0xFFFF)); } static inline sysname_t fetch_recipient(uint32_t id) { return id >> 24; } static inline sysname_t fetch_request_id(uint32_t id) { return id & 0x00FFFFFF; } void __sys_internal_listener_loop(uint32_t *request, uint32_t request_size) { sysname_t id = me(); uint32_t self_fifo_info; uint32_t from_host_fifo_info; uint32_t to_host_fifo_info; self_fifo_info = fifo_fetch_info(id); from_host_fifo_info = fifo_sys_fetch_info(0); to_host_fifo_info = fifo_sys_fetch_info(1); while (true) { if (fetch_request(self_fifo_info, request, request_size)) { while (fifo_is_full(to_host_fifo_info, request_size)) { // Waiting for the recipient to read some of its pending requests... // Do we want to add some "sleep" here? } fifo_produce(to_host_fifo_info, request, request_size); } if (fetch_request(from_host_fifo_info, request, request_size)) { sysname_t recipient = fetch_recipient(request[0]); /* If a message is sent to the listener from the host, we interpret it as a shutdown order. */ if (recipient == id) break; request[0] = fetch_request_id(request[0]); extern void internal_actor_send(uint32_t recipient, uint32_t * request, uint32_t request_size); internal_actor_send(recipient, request, request_size); } // Waiting for some request... // Do we want to add some "sleep" here? } } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/lshrdi3.c ================================================ /* ===-- lshrdi3.c - Implement __lshrdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __lshrdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: logical a >> b */ /* Precondition: 0 <= b < bits_in_dword */ COMPILER_RT_ABI di_int __lshrdi3(di_int a, si_int b) { const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); udwords input; udwords result; input.all = a; if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { result.s.high = 0; result.s.low = input.s.high >> (b - bits_in_word); } else /* 0 <= b < bits_in_word */ { if (b == 0) return a; result.s.high = input.s.high >> b; result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); } return result.all; } #if defined(__ARM_EABI__) AEABI_RTABI di_int __aeabi_llsr(di_int a, si_int b) { return __lshrdi3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/macro_utils.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MACRO_UTILS_H #define DPUSYSCORE_MACRO_UTILS_H /** * @file macro_utils.h * @brief Provide utility macros. */ #define __STR(x) __STR_AGAIN(x) #define __STR_AGAIN(x) #x #define __CONCAT(x, y) __CONCAT_AGAIN(x, y) #define __CONCAT_AGAIN(x, y) x##y #define __REPEAT_0(x) #define __REPEAT_1(x) x(0) __REPEAT_0(x) #define __REPEAT_2(x) x(1) __REPEAT_1(x) #define __REPEAT_3(x) x(2) __REPEAT_2(x) #define __REPEAT_4(x) x(3) __REPEAT_3(x) #define __REPEAT_5(x) x(4) __REPEAT_4(x) #define __REPEAT_6(x) x(5) __REPEAT_5(x) #define __REPEAT_7(x) x(6) __REPEAT_6(x) #define __REPEAT_8(x) x(7) __REPEAT_7(x) #define __REPEAT_9(x) x(8) __REPEAT_8(x) #define __REPEAT_10(x) x(9) __REPEAT_9(x) #define __REPEAT_11(x) x(10) __REPEAT_10(x) #define __REPEAT_12(x) x(11) __REPEAT_11(x) #define __REPEAT_13(x) x(12) __REPEAT_12(x) #define __REPEAT_14(x) x(13) __REPEAT_13(x) #define __REPEAT_15(x) x(14) __REPEAT_14(x) #define __REPEAT_16(x) x(15) __REPEAT_15(x) #define __REPEAT_17(x) x(16) __REPEAT_16(x) #define __REPEAT_18(x) x(17) __REPEAT_17(x) #define __REPEAT_19(x) x(18) __REPEAT_18(x) #define __REPEAT_20(x) x(19) __REPEAT_19(x) #define __REPEAT_21(x) x(20) __REPEAT_20(x) #define __REPEAT_22(x) x(21) __REPEAT_21(x) #define __REPEAT_23(x) x(22) __REPEAT_22(x) #define __REPEAT_24(x) x(23) __REPEAT_23(x) #define __FOR_EACH_THREAD(x) __CONCAT(__REPEAT_, NR_THREADS)(x) #endif /* DPUSYSCORE_MACRO_UTILS_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mcount.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ void __attribute__((naked, noinline, no_instrument_function)) mcount(void) { // Please see ret_mcount comment regarding why mcount references ret_mcount. __asm__ volatile("jump ret_mcount"); } void __attribute__((naked, noinline, no_instrument_function)) ret_mcount(void) { // ret_mcount is used in statistics mode, mcount *must* reference ret_mcount // so that ret_mcount symbol is not gc (remember that we patch the binary // when copying it to iram). __asm__ volatile("sh id4, thread_profiling, r23\n" "jump r23"); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/moddi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 signed division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); int64_t __moddi3(int64_t dividend, int64_t divider) { if (dividend >= 0) { if (divider >= 0) { return __udiv64(dividend, divider, 1); } else { return __udiv64(dividend, -divider, 1); } } else if (divider >= 0) { // Negative dividend, positive divider return -__udiv64(-dividend, divider, 1); } else { // Negative dividend, negative divider return -__udiv64(-dividend, -divider, 1); } } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/modsi3.c ================================================ /* ===-- modsi3.c - Implement __modsi3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __modsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a % b */ extern long __div32(int, int); COMPILER_RT_ABI si_int __modsi3(si_int a, si_int b) { long res = __div32(a, b); return (int)res; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mram.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MRAM_H #define DPUSYSCORE_MRAM_H #include #include /** * @file mram.h * @brief MRAM Transfer Management. */ #define DPU_MRAM_HEAP_POINTER ((__mram_ptr void *)(&__sys_used_mram_end)) extern __mram_ptr __dma_aligned uint8_t __sys_used_mram_end[0]; /** * @fn mram_read * @brief Stores the specified number of bytes from MRAM to WRAM. * The number of bytes must be: * - at least 8 * - at most 2048 * - a multiple of 8 * * @param from source address in MRAM * @param to destination address in WRAM * @param nb_of_bytes number of bytes to transfer */ static inline void mram_read(const __mram_ptr void *from, void *to, unsigned int nb_of_bytes) { __builtin_dpu_ldma(to, from, nb_of_bytes); } /** * @fn mram_write * @brief Stores the specified number of bytes from WRAM to MRAM. * The number of bytes must be: * - at least 8 * - at most 2048 * - a multiple of 8 * * @param from source address in WRAM * @param to destination address in MRAM * @param nb_of_bytes number of bytes to transfer */ static inline void mram_write(const void *from, __mram_ptr void *to, unsigned int nb_of_bytes) { __builtin_dpu_sdma(from, to, nb_of_bytes); } #endif /* DPUSYSCORE_MRAM_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mul32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include int __attribute__((noinline)) __mulsi3(int a, int b) { int dest; __asm__ volatile(" jgtu %2, %1, __mulsi3_swap\n" " move r2, %1\n" " move r0, %2, true, __mulsi3_start\n" "__mulsi3_swap:\n" " move r2, %2\n" " move r0, %1\n" "__mulsi3_start:\n" " move r1, zero\n" " mul_step d0, r2, d0, 0 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 1 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 2 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 3 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 4 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 5 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 6 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 7 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 8 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 9 , z, __mulsi3_exit\n" " mul_step d0, r2, d0, 10, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 11, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 12, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 13, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 14, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 15, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 16, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 17, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 18, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 19, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 20, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 21, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 22, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 23, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 24, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 25, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 26, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 27, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 28, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 29, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 30, z, __mulsi3_exit\n" " mul_step d0, r2, d0, 31, z, __mulsi3_exit\n" "__mulsi3_exit:\n" " move %0, r1\n" : "=r"(dest) : "r"(a), "r"(b)); return dest; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mul64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 multiplication emulation. * * A relatively fast emulation of 64x64 multiplication using byte multipliers. * Basically, the two operands X and Y are seen as byte polynomials: * - X = X0.2^0 + X1.2^8 + X2.2^16 + X3.2^24 + X4.2^32 + X5.2^40 + X6.2^48 + X7.2^56 * - Y = Y0.2^0 + Y1.2^8 + Y2.2^16 + Y3.2^24 + Y4.2^32 + Y5.2^40 + Y6.2^48 + Y7.2^56 * * The product Z is expressed as a similar polynomial. Since the result is 64 bits, * the function drops any coefficient for a power greater than 56, hence the following * formula: * Z = (X0.Y0).2^0 * + (X0.Y1 + X1.Y0).2^8 * + (X0.Y2 + X2.Y0 + X1.Y1).2^16 * + (X0.Y3 + X1.Y2 + X2.Y1 + X3.Y0).2^24 * + (X0.Y4 + X1.Y3 + X2.Y2 + X3.Y1 + X4.Y0).2^32 * etc. * * Each individual produce is computed with the native built-in 8x8 instructions. * Resulting processing time is in the magnitude of 150 instructions. * * The two operands are found in __D0 and the first kernel nano-stack entry. * The result goes into __R0 (lsbits) and __R1 (msbits). * Also, __R2 contains the return address register, instead of __RET__. */ #include static uint16_t _mul00(uint32_t a, uint32_t b) { #ifndef DPU return (a & 0xff) * (b & 0xff); #else uint32_t r; __asm__ volatile("mul_ul_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } static uint16_t _mul01(uint32_t a, uint32_t b) { #ifndef DPU return (a & 0xff) * ((b >> 8) & 0xff); #else uint32_t r; __asm__ volatile("mul_ul_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } #define _mul02(a, b) _mul00(a, (b >> 16)) #define _mul03(a, b) _mul01(a, (b >> 16)) static uint16_t _mul11(uint32_t a, uint32_t b) { #ifndef DPU return ((a >> 8) & 0xff) * ((b >> 8) & 0xff); #else uint32_t r; __asm__ volatile("mul_uh_uh %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(b) :); return r; #endif } static uint16_t _mul12(uint32_t a, uint32_t b) { #ifndef DPU return ((a >> 8) & 0xff) * ((b >> 16) & 0xff); #else uint32_t r = (b >> 16); __asm__ volatile("mul_uh_ul %[rc_wr32], %[ra_r32], %[rb_wr32]" : [rc_wr32] "=r"(r) : [ra_r32] "r"(a), [rb_wr32] "r"(r) :); return r; #endif } #define _mul13(a, b) _mul11(a, (b >> 16)) #define _mul22(a, b) _mul00((a >> 16), (b >> 16)) #define _mul23(a, b) _mul01((a >> 16), (b >> 16)) #define _mul33(a, b) _mul11((a >> 16), (b >> 16)) #define mulx0y0(xl, yl) _mul00(xl, yl) #define mulx0y1(xl, yl) _mul01(xl, yl) #define mulx0y2(xl, yl) _mul02(xl, yl) #define mulx0y3(xl, yl) _mul03(xl, yl) #define mulx0y4(xl, yh) _mul00(xl, yh) #define mulx0y5(xl, yh) _mul01(xl, yh) #define mulx0y6(xl, yh) _mul02(xl, yh) #define mulx0y7(xl, yh) _mul03(xl, yh) #define mulx1y1(xl, yl) _mul11(xl, yl) #define mulx1y2(xl, yl) _mul12(xl, yl) #define mulx1y3(xl, yl) _mul13(xl, yl) #define mulx1y4(xl, yh) _mul01(yh, xl) #define mulx1y5(xl, yh) _mul11(xl, yh) #define mulx1y6(xl, yh) _mul12(xl, yh) #define mulx2y2(xl, yl) _mul22(xl, yl) #define mulx2y3(xl, yl) _mul23(xl, yl) #define mulx2y4(xl, yh) _mul02(yh, xl) #define mulx2y5(xl, yh) _mul12(yh, xl) #define mulx3y3(xl, yl) _mul33(xl, yl) #define mulx3y4(xl, yh) _mul03(yh, xl) // Symmetry... #define mulx1y0(xl, yl) mulx0y1(yl, xl) #define mulx2y0(xl, yl) mulx0y2(yl, xl) #define mulx2y1(xl, yl) mulx1y2(yl, xl) #define mulx3y0(xl, yl) mulx0y3(yl, xl) #define mulx3y1(xl, yl) mulx1y3(yl, xl) #define mulx3y2(xl, yl) mulx2y3(yl, xl) #define mulx4y0(xh, yl) mulx0y4(yl, xh) #define mulx4y1(xh, yl) mulx1y4(yl, xh) #define mulx4y2(xh, yl) mulx2y4(yl, xh) #define mulx4y3(xh, yl) mulx3y4(yl, xh) #define mulx5y0(xh, yl) mulx0y5(yl, xh) #define mulx5y1(xh, yl) mulx1y5(yl, xh) #define mulx5y2(xh, yl) mulx2y5(yl, xh) #define mulx6y0(xh, yl) mulx0y6(yl, xh) #define mulx6y1(xh, yl) mulx1y6(yl, xh) #define mulx7y0(xh, yl) mulx0y7(yl, xh) uint64_t __muldi3(uint64_t x, uint64_t y) { uint32_t xl = x; uint32_t xh = ((uint64_t)x >> 32); uint32_t yl = y; uint32_t yh = ((uint64_t)y >> 32); // Each fragment of the product. uint32_t p0, p1, p2, p3, p4, p5, p6, p7, rh; uint64_t rl; p0 = mulx0y0(xl, yl); rl = (uint64_t)p0; p1 = mulx0y1(xl, yl) + mulx1y0(xl, yl); rl += ((uint64_t)p1 << 8); p2 = mulx0y2(xl, yl) + mulx2y0(xl, yl) + mulx1y1(xl, yl); rl += ((uint64_t)p2 << 16); p3 = mulx0y3(xl, yl) + mulx3y0(xl, yl) + mulx1y2(xl, yl) + mulx2y1(xl, yl); rl += ((uint64_t)p3 << 24); p4 = mulx0y4(xl, yh) + mulx4y0(xh, yl) + mulx1y3(xl, yl) + mulx3y1(xl, yl) + mulx2y2(xl, yl); rh = p4; p5 = mulx0y5(xl, yh) + mulx5y0(xh, yl) + mulx1y4(xl, yh) + mulx4y1(xh, yl) + mulx2y3(xl, yl) + mulx3y2(xl, yl); rh += p5 << 8; p6 = mulx0y6(xl, yh) + mulx6y0(xh, yl) + mulx1y5(xl, yh) + mulx5y1(xh, yl) + mulx2y4(xl, yh) + mulx4y2(xh, yl) + mulx3y3(xl, yl); rh += p6 << 16; p7 = mulx0y7(xl, yh) + mulx7y0(xh, yl) + mulx1y6(xl, yh) + mulx6y1(xh, yl) + mulx2y5(xl, yh) + mulx5y2(xh, yl) + mulx3y4(xl, yh) + mulx4y3(xh, yl); rh += p7 << 24; return rl + (((uint64_t)rh) << 32); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/muldc3.c ================================================ /* ===-- muldc3.c - Implement __muldc3 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __muldc3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" #include "int_math.h" /* Returns: the product of a + ib and c + id */ COMPILER_RT_ABI Dcomplex __muldc3(double __a, double __b, double __c, double __d) { double __ac = __a * __c; double __bd = __b * __d; double __ad = __a * __d; double __bc = __b * __c; Dcomplex z; COMPLEX_REAL(z) = __ac - __bd; COMPLEX_IMAGINARY(z) = __ad + __bc; if (crt_isnan(COMPLEX_REAL(z)) && crt_isnan(COMPLEX_IMAGINARY(z))) { int __recalc = 0; if (crt_isinf(__a) || crt_isinf(__b)) { __a = crt_copysign(crt_isinf(__a) ? 1 : 0, __a); __b = crt_copysign(crt_isinf(__b) ? 1 : 0, __b); if (crt_isnan(__c)) __c = crt_copysign(0, __c); if (crt_isnan(__d)) __d = crt_copysign(0, __d); __recalc = 1; } if (crt_isinf(__c) || crt_isinf(__d)) { __c = crt_copysign(crt_isinf(__c) ? 1 : 0, __c); __d = crt_copysign(crt_isinf(__d) ? 1 : 0, __d); if (crt_isnan(__a)) __a = crt_copysign(0, __a); if (crt_isnan(__b)) __b = crt_copysign(0, __b); __recalc = 1; } if (!__recalc && (crt_isinf(__ac) || crt_isinf(__bd) || crt_isinf(__ad) || crt_isinf(__bc))) { if (crt_isnan(__a)) __a = crt_copysign(0, __a); if (crt_isnan(__b)) __b = crt_copysign(0, __b); if (crt_isnan(__c)) __c = crt_copysign(0, __c); if (crt_isnan(__d)) __d = crt_copysign(0, __d); __recalc = 1; } if (__recalc) { COMPLEX_REAL(z) = CRT_INFINITY * (__a * __c - __b * __d); COMPLEX_IMAGINARY(z) = CRT_INFINITY * (__a * __d + __b * __c); } } return z; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/muldf3.c ================================================ //===-- lib/muldf3.c - Double-precision multiplication ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float multiplication // with the IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_mul_impl.inc" COMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dmul(fp_t a, fp_t b) { return __muldf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mulodi4.c ================================================ /*===-- mulodi4.c - Implement __mulodi4 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulodi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: sets *overflow to 1 if a * b overflows */ COMPILER_RT_ABI di_int __mulodi4(di_int a, di_int b, int *overflow) { const int N = (int)(sizeof(di_int) * CHAR_BIT); const di_int MIN = (di_int)1 << (N - 1); const di_int MAX = ~MIN; *overflow = 0; di_int result = a * b; if (a == MIN) { if (b != 0 && b != 1) *overflow = 1; return result; } if (b == MIN) { if (a != 0 && a != 1) *overflow = 1; return result; } di_int sa = a >> (N - 1); di_int abs_a = (a ^ sa) - sa; di_int sb = b >> (N - 1); di_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return result; if (sa == sb) { if (abs_a > MAX / abs_b) *overflow = 1; } else { if (abs_a > MIN / -abs_b) *overflow = 1; } return result; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mulosi4.c ================================================ /*===-- mulosi4.c - Implement __mulosi4 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulosi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: sets *overflow to 1 if a * b overflows */ COMPILER_RT_ABI si_int __mulosi4(si_int a, si_int b, int *overflow) { const int N = (int)(sizeof(si_int) * CHAR_BIT); const si_int MIN = (si_int)1 << (N - 1); const si_int MAX = ~MIN; *overflow = 0; si_int result = a * b; if (a == MIN) { if (b != 0 && b != 1) *overflow = 1; return result; } if (b == MIN) { if (a != 0 && a != 1) *overflow = 1; return result; } si_int sa = a >> (N - 1); si_int abs_a = (a ^ sa) - sa; si_int sb = b >> (N - 1); si_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return result; if (sa == sb) { if (abs_a > MAX / abs_b) *overflow = 1; } else { if (abs_a > MIN / -abs_b) *overflow = 1; } return result; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mulsf3.c ================================================ //===-- lib/mulsf3.c - Single-precision multiplication ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float multiplication // with the IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_mul_impl.inc" COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { return __mulXf3__(a, b); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fmul(fp_t a, fp_t b) { return __mulsf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mulvdi3.c ================================================ /*===-- mulvdi3.c - Implement __mulvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: aborts if a * b overflows */ COMPILER_RT_ABI di_int __mulvdi3(di_int a, di_int b) { const int N = (int)(sizeof(di_int) * CHAR_BIT); const di_int MIN = (di_int)1 << (N - 1); const di_int MAX = ~MIN; if (a == MIN) { if (b == 0 || b == 1) return a * b; compilerrt_abort(); } if (b == MIN) { if (a == 0 || a == 1) return a * b; compilerrt_abort(); } di_int sa = a >> (N - 1); di_int abs_a = (a ^ sa) - sa; di_int sb = b >> (N - 1); di_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return a * b; if (sa == sb) { if (abs_a > MAX / abs_b) compilerrt_abort(); } else { if (abs_a > MIN / -abs_b) compilerrt_abort(); } return a * b; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mulvsi3.c ================================================ /* ===-- mulvsi3.c - Implement __mulvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __mulvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a * b */ /* Effects: aborts if a * b overflows */ COMPILER_RT_ABI si_int __mulvsi3(si_int a, si_int b) { const int N = (int)(sizeof(si_int) * CHAR_BIT); const si_int MIN = (si_int)1 << (N - 1); const si_int MAX = ~MIN; if (a == MIN) { if (b == 0 || b == 1) return a * b; compilerrt_abort(); } if (b == MIN) { if (a == 0 || a == 1) return a * b; compilerrt_abort(); } si_int sa = a >> (N - 1); si_int abs_a = (a ^ sa) - sa; si_int sb = b >> (N - 1); si_int abs_b = (b ^ sb) - sb; if (abs_a < 2 || abs_b < 2) return a * b; if (sa == sb) { if (abs_a > MAX / abs_b) compilerrt_abort(); } else { if (abs_a > MIN / -abs_b) compilerrt_abort(); } return a * b; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/mutex.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_MUTEX_H #define DPUSYSCORE_MUTEX_H /** * @file mutex.h * @brief Mutual exclusions. * * A mutex ensures mutual exclusion between threads: only one runtime can have the mutex at a time, blocking all the * other threads trying to take the mutex. * * @internal All the mutexes are stored in a table in WRAM. In this table, each byte represents a mutex, * and can be accessed directly by taking the base address of the table and adding it the sysname of the mutex * we want (thus, the sysname should be an integer in the range [0; NB_MUTEX -1]). The result of * this addition is what a mutex_get will return. * A lock is made by using an lb_a instruction on the address of the mutex given as a parameter. * An unlock is made by using an sb_r instruction on the address of the mutex given as a parameter. * The id of the runtime doing the unlock is what is currently stored at the address of the mutex. * The base address of this table is associated with the pointer defined by __MUTEX_TABLE__. */ #include #include #include #include /** * @typedef mutex_id_t * @brief A mutex object reference, as declared by MUTEX_INIT. */ typedef uint8_t *mutex_id_t; /** * @def MUTEX_GET * @hideinitializer * @brief Return the symbol to use when using the mutex associated to the given name. */ #define MUTEX_GET(_name) _name /** * @def MUTEX_INIT * @hideinitializer * @brief Declare and initialize a mutex associated to the given name. */ #define MUTEX_INIT(_name) \ ATOMIC_BIT_INIT(__CONCAT(mutex_, _name)); \ const mutex_id_t MUTEX_GET(_name) = &ATOMIC_BIT_GET(__CONCAT(mutex_, _name)) /** * @fn mutex_lock * @brief Takes the lock on the given mutex. * @param mutex the mutex we want to lock */ static inline void mutex_lock(mutex_id_t mutex) { __asm__ volatile("acquire %[mtx], 0, nz, ." : : [mtx] "r"(mutex) :); } /** * @fn mutex_trylock * @brief Tries to take the lock on the given mutex. If the lock is already taken, returns immediately. * @param mutex the mutex we want to lock * @return Whether the mutex has been successfully locked. */ static inline bool mutex_trylock(mutex_id_t mutex) { bool result = true; __asm__ volatile("acquire %[mtx], 0, z, .+2; move %[res], 0" : [res] "+r"(result) : [mtx] "r"(mutex) :); return result; } /** * @fn mutex_unlock * @brief Releases the lock on the given mutex. * @param mutex the mutex we want to unlock */ static inline void mutex_unlock(mutex_id_t mutex) { __asm__ volatile("release %[mtx], 0, nz, .+1" : : [mtx] "r"(mutex) :); } #endif /* DPUSYSCORE_MUTEX_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/negdf2.c ================================================ //===-- lib/negdf2.c - double-precision negation ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float negation. // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __negdf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dneg(fp_t a) { return __negdf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/negdi2.c ================================================ /* ===-- negdi2.c - Implement __negdi2 -------------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ COMPILER_RT_ABI di_int __negdi2(di_int a) { /* Note: this routine is here for API compatibility; any sane compiler * should expand it inline. */ return -a; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/negsf2.c ================================================ //===-- lib/negsf2.c - single-precision negation ------------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float negation. // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" COMPILER_RT_ABI fp_t __negsf2(fp_t a) { return fromRep(toRep(a) ^ signBit); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fneg(fp_t a) { return __negsf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/negvdi2.c ================================================ /* ===-- negvdi2.c - Implement __negvdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negvdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ /* Effects: aborts if -a overflows */ COMPILER_RT_ABI di_int __negvdi2(di_int a) { const di_int MIN = (di_int)1 << ((int)(sizeof(di_int) * CHAR_BIT) - 1); if (a == MIN) compilerrt_abort(); return -a; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/negvsi2.c ================================================ /* ===-- negvsi2.c - Implement __negvsi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __negvsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: -a */ /* Effects: aborts if -a overflows */ COMPILER_RT_ABI si_int __negvsi2(si_int a) { const si_int MIN = (si_int)1 << ((int)(sizeof(si_int) * CHAR_BIT) - 1); if (a == MIN) compilerrt_abort(); return -a; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/paritydi2.c ================================================ /* ===-- paritydi2.c - Implement __paritydi2 -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __paritydi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: 1 if number of bits is odd else returns 0 */ COMPILER_RT_ABI si_int __paritydi2(di_int a) { dwords x; x.all = a; return __paritysi2(x.s.high ^ x.s.low); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/paritysi2.c ================================================ /* ===-- paritysi2.c - Implement __paritysi2 -------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __paritysi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: 1 if number of bits is odd else returns 0 */ COMPILER_RT_ABI si_int __paritysi2(si_int a) { su_int x = (su_int)a; x ^= x >> 16; x ^= x >> 8; x ^= x >> 4; return (0x6996 >> (x & 0xF)) & 1; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/perfcounter.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #define BIT_IMPRECISION 4 perfcounter_t perfcounter_get(void) { uint32_t reg_value; __asm__ volatile("time %[r]" : [r] "=r"(reg_value)); return ((perfcounter_t)reg_value) << BIT_IMPRECISION; } #ifndef DPU_PROFILING perfcounter_t perfcounter_config(perfcounter_config_t config, bool reset_value) { uint32_t reg_value; uint32_t reg_config = (reset_value ? 1 : 0) | (config << 1); __asm__ volatile("time_cfg %[r], %[c]" : [r] "=r"(reg_value) : [c] "r"(reg_config)); return ((perfcounter_t)reg_value) << BIT_IMPRECISION; } #endif /* !DPU_PROFILING */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/perfcounter.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_PERFCOUNTER_H #define DPUSYSCORE_PERFCOUNTER_H #include #include /** * @file perfcounter.h * @brief Utilities concerning the performance counter register. * */ /** * @typedef perfcounter_t * @brief A value which can be stored by the performance counter. */ typedef uint64_t perfcounter_t; /** * @enum perfcounter_config_t * @brief A configuration for the performance counter, defining what should be counted. * * @var COUNT_SAME keep the previous configuration * @var COUNT_CYCLES switch to counting clock cycles * @var COUNT_INSTRUCTIONS switch to counting executed instructions * @var COUNT_NOTHING does not count anything */ typedef enum _perfcounter_config_t { COUNT_SAME = 0, COUNT_CYCLES = 1, COUNT_INSTRUCTIONS = 2, COUNT_NOTHING = 3, } perfcounter_config_t; /** * @def CLOCKS_PER_SEC * @hideinitializer * @brief A number used to convert the value returned by the perfcounter_get and perfcounter_config functions into seconds, * when counting clock cycles. */ extern const volatile uint32_t CLOCKS_PER_SEC; /** * @fn perfcounter_get * @brief Fetch the value of the performance counter register. * * @return The current value of the performance counter register, or undefined if perfcounter_config has not been called before. */ perfcounter_t perfcounter_get(void); #ifndef DPU_PROFILING /** * @fn perfcounter_config * @brief Configure the performance counter behavior. * * This function cannot be used when profiling an application. * * @param config The new behavior for the performance counter register * @param reset_value Whether the performance counter register should be set to 0 * * @return The current value of the performance counter register, or undefined if perfcounter_config has not been called before. */ perfcounter_t perfcounter_config(perfcounter_config_t config, bool reset_value); #else #define perfcounter_config(config, reset_value) \ do { \ } while (0) #endif /* !DPU_PROFILING */ #endif /* DPUSYSCORE_PERFCOUNTER_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/popcountdi2.c ================================================ /* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __popcountdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: count of 1 bits */ COMPILER_RT_ABI si_int __popcountdi2(di_int a) { du_int x2 = (du_int)a; x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL); /* Every 2 bits holds the sum of every pair of bits (32) */ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL); /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL; /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */ su_int x = (su_int)(x2 + (x2 >> 32)); /* The lower 32 bits hold four 16 bit sums (5 significant bits). */ /* Upper 32 bits are garbage */ x = x + (x >> 16); /* The lower 16 bits hold two 32 bit sums (6 significant bits). */ /* Upper 16 bits are garbage */ return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */ } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/popcountsi2.c ================================================ /* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __popcountsi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: count of 1 bits */ COMPILER_RT_ABI si_int __popcountsi2(si_int a) { su_int x = (su_int)a; x = x - ((x >> 1) & 0x55555555); /* Every 2 bits holds the sum of every pair of bits */ x = ((x >> 2) & 0x33333333) + (x & 0x33333333); /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */ x = (x + (x >> 4)) & 0x0F0F0F0F; /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */ x = (x + (x >> 16)); /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/ /* Upper 16 bits are garbage */ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */ } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/powidf2.c ================================================ /* ===-- powidf2.cpp - Implement __powidf2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __powidf2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a ^ b */ COMPILER_RT_ABI double __powidf2(double a, si_int b) { const int recip = b < 0; double r = 1; while (1) { if (b & 1) r *= a; b /= 2; if (b == 0) break; a *= a; } return recip ? 1 / r : r; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/powisf2.c ================================================ /*===-- powisf2.cpp - Implement __powisf2 ---------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __powisf2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a ^ b */ COMPILER_RT_ABI float __powisf2(float a, si_int b) { const int recip = b < 0; float r = 1; while (1) { if (b & 1) r *= a; b /= 2; if (b == 0) break; a *= a; } return recip ? 1 / r : r; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/profiling.c ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #ifdef DPU_PROFILING void __attribute__((no_instrument_function)) profiling_start(dpu_profiling_t *context) { thread_id_t tid = me(); uint32_t perfcounter_value; if (unlikely(context->start[tid] != PROFILING_RESET_VALUE)) { __asm__("fault " __STR(__FAULT_ALREADY_PROFILING__)); unreachable(); } __asm__ volatile("time %[r]" : [r] "=r"(perfcounter_value)); context->start[tid] = perfcounter_value; } void __attribute__((no_instrument_function)) profiling_stop(dpu_profiling_t *context) { thread_id_t tid = me(); uint32_t perfcounter_value; if (unlikely(context->start[tid] == PROFILING_RESET_VALUE)) { __asm__("fault " __STR(__FAULT_NOT_PROFILING__)); unreachable(); } __asm__ volatile("time %[r]" : [r] "=r"(perfcounter_value)); context->count[tid] += perfcounter_value - context->start[tid]; context->start[tid] = PROFILING_RESET_VALUE; } #endif /* DPU_PROFILING */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/profiling.h ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_PROFILING_H #define DPUSYSCORE_PROFILING_H /** * @file profiling.h * @brief Code section profiling management. */ #include #include #include #define PROFILING_RESET_VALUE (UINT32_MAX) /** * @def PROFILING_INIT * @hideinitializer * @brief Declare and initialize a profiling context associated to the given name. */ #define PROFILING_INIT(_name) \ __section(".dpu_profiling") dpu_profiling_t _name = { \ .start = { [0 ...(NR_THREADS - 1)] = PROFILING_RESET_VALUE }, \ .count = { [0 ...(NR_THREADS - 1)] = 0 }, \ } #ifdef DPU_PROFILING /** * @fn profiling_start * @brief Start profiling a code section. * * This function saves the perfcounter current value in the profiling context. * * @param context the profiling context to use. */ void profiling_start(dpu_profiling_t *context); /** * @fn profiling_stop * @brief Stop profiling a code section. * * This function gets the perfcounter current value and computes the number of cyles spent in the code section. * The profiling_start function must be called beforehand. * * @param context the profiling context to use. */ void profiling_stop(dpu_profiling_t *context); #else #define profiling_start(context) \ do { \ } while (0) #define profiling_stop(context) \ do { \ } while (0) #endif /* DPU_PROFILING */ #endif /* DPUSYSCORE_PROFILING_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/profiling_internals.h ================================================ /* Copyright 2021 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* Shared with backends */ #ifndef DPUSYSCORE_PROFILING_INTERNALS_H #define DPUSYSCORE_PROFILING_INTERNALS_H /** * @file profiling_internals.h * @brief Code section profiling internals. */ #include #ifndef NR_THREADS #ifdef DPU_NR_THREADS #define NR_THREADS DPU_NR_THREADS #else #error "DPU_NR_THREADS and NR_THREADS are undefined" #endif /* DPU_NR_THREADS */ #endif /* !NR_THREADS */ /** * @typedef dpu_profiling_t * @brief A profiling context. */ typedef struct { uint32_t start[NR_THREADS]; uint32_t count[NR_THREADS]; } dpu_profiling_t; #endif /* DPUSYSCORE_PROFILING_INTERNALS_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/sem.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include void sem_take(struct sem_t *sem) { unsigned char lock = sem->lock; __acquire(lock, "0"); char count = sem->count - 1; thread_id_t tid = me(); if (count < 0) { unsigned char last = sem->wait_queue; if (last != __EMPTY_WAIT_QUEUE) { unsigned char first = __WAIT_QUEUE_TABLE[last]; __WAIT_QUEUE_TABLE[tid] = first; __WAIT_QUEUE_TABLE[last] = tid; } else { __WAIT_QUEUE_TABLE[tid] = tid; } sem->wait_queue = tid; sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); __stop(); } else { sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); } } void sem_give(struct sem_t *sem) { unsigned char lock = sem->lock; __acquire(lock, "0"); unsigned char count = sem->count + 1; unsigned char last = sem->wait_queue; if (last != __EMPTY_WAIT_QUEUE) { unsigned char first = __WAIT_QUEUE_TABLE[last]; if (first == last) { sem->wait_queue = __EMPTY_WAIT_QUEUE; } else { __WAIT_QUEUE_TABLE[last] = __WAIT_QUEUE_TABLE[first]; } __resume(first, "0"); } sem->count = count; __release(lock, "0", __AT_NEXT_INSTRUCTION); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/sem.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SEM_H #define DPUSYSCORE_SEM_H /** * @file sem.h * @brief Synchronization with semaphores. * * A semaphore is characterized by a counter and a wait queue. It provides two functions: * * - Take: the counter is decremented by 1. If the counter is negative, the runtime is blocked (stop) and placed in the * semaphore's wait queue, waiting to be resume by another runtime. * - Give: the counter is incremented by 1. If the counter was negative before the increment, the runtime resumes the execution * of the first runtime waiting in the waiting queue. In all the cases, the runtime continues its own execution. * */ #include #include #include /** * @typedef sem_t * @brief A semaphore object, as declared by SEMAPHORE_INIT. */ typedef struct sem_t { uint8_t wait_queue; uint8_t count; uint8_t initial_count; uint8_t lock; } sem_t; /** * @def SEMAPHORE_INIT * @hideinitializer * @brief Declare and initialize a semaphore associated to the given name. */ /* clang-format off */ #define SEMAPHORE_INIT(_name, _counter) \ _Static_assert((_counter < 128) && (_counter >= -127), "semaphore counter must be encoded on a byte"); \ ATOMIC_BIT_INIT(__CONCAT(semaphore_, _name)); \ extern sem_t (_name); \ __asm__(".section .data." __STR(_name) "\n" \ ".type " __STR(_name) ",@object\n" \ ".globl " __STR(_name) "\n" \ ".p2align 2\n" __STR(_name) ":\n" \ ".byte 0xFF\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(_counter) "\n" \ ".byte " __STR(ATOMIC_BIT_GET(__CONCAT(semaphore_, _name))) "\n" \ ".size " __STR(_name) ", 4\n" \ ".text"); /* clang-format on */ /** * @fn sem_take * @brief Takes one unit in the given semaphore (cf Take definition). * @param sem the semaphore we want to take */ void sem_take(sem_t *sem); /** * @fn sem_give * @brief Gives on unit in the given semaphore (cf Give definition). * @param sem the semaphore we want to give */ void sem_give(sem_t *sem); #endif /* DPUSYSCORE_SEM_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SEQREAD_H #define DPUSYSCORE_SEQREAD_H /** * @file seqread.h * @brief Sequential reading of items in MRAM. * * A sequential reader allows to parse a contiguous area in MRAM in sequence. * For example, if the MRAM contains an array of N structures, a sequential * reader on this array will automatically fetch the data into WRAM, thus * simplify the iterative loop on the elements. * * The size of cached area is defined by default but can be overriden by * defining this value in SEQREAD_CACHE_SIZE. * * The use of a sequential reader implies: * * - first, to allocate some storage in WRAM to cache the items, using seqread_alloc. * - then to initialize a reader on the MRAM area, via seqread_init * - finally to iterate on the elements, invoking seqread_get whenever a new item is accessed. * */ #include #include #include #ifndef SEQREAD_CACHE_SIZE /** * @def SEQREAD_CACHE_SIZE * @hideinitializer * @brief Size of caches used by seqread. */ #define SEQREAD_CACHE_SIZE 256 #endif _Static_assert(SEQREAD_CACHE_SIZE == 32 || SEQREAD_CACHE_SIZE == 64 || SEQREAD_CACHE_SIZE == 128 || SEQREAD_CACHE_SIZE == 256 || SEQREAD_CACHE_SIZE == 512 || SEQREAD_CACHE_SIZE == 1024, "seqread error: invalid cache size defined"); #define __SEQREAD_FCT(suffix) __CONCAT(__CONCAT(seqread, SEQREAD_CACHE_SIZE), suffix) #define __SEQREAD_ALLOC __SEQREAD_FCT(_alloc) #define __SEQREAD_INIT __SEQREAD_FCT(_init) #define __SEQREAD_GET __SEQREAD_FCT(_get) #define __SEQREAD_TELL __SEQREAD_FCT(_tell) #define __SEQREAD_SEEK __SEQREAD_FCT(_seek) /** * @typedef seqreader_buffer_t * @brief An buffer to use to initial a sequential reader. */ typedef uintptr_t seqreader_buffer_t; /** * @typedef seqreader_t * @brief An object used to perform sequential reading of MRAM. */ typedef struct { seqreader_buffer_t wram_cache; uintptr_t mram_addr; } seqreader_t; seqreader_buffer_t __SEQREAD_ALLOC(); /** * @fn seqread_alloc * @brief Initializes an area in WRAM to cache the read buffers. * * Notice that this buffer can be re-used for different sequential reads, * as long as it is initialized each time to a new buffer in MRAM. * * @return A pointer to the allocated cache base address. */ #define seqread_alloc __SEQREAD_ALLOC void * __SEQREAD_INIT(seqreader_buffer_t cache, __mram_ptr void *mram_addr, seqreader_t *reader); /** * @fn seqread_init * @brief Creates a sequential reader. * * The reader is associated to an existing cache in WRAM, created with * seqread_alloc and a contiguous area of data in MRAM. The function * loads the first pages of data into the cache and provides a pointer * to the first byte in cache actually mapping the expected data. * * Notice that the provided MRAM address does not need to be aligned on * any constraint: the routine does the alignment automatically. * * @param cache the reader's cache in WRAM * @param mram_addr the buffer address in MRAM * @param reader the sequential reader to init to the supplied MRAM address * @return A ptr to the first byte in cache corresponding to the MRAM address */ #define seqread_init __SEQREAD_INIT void * __SEQREAD_GET(void *ptr, uint32_t inc, seqreader_t *reader); /** * @fn seqread_get * @brief Fetches the next item in a sequence. * * This operation basically consists in incrementing the pointer that goes * through the mapped area of memory. The function automatically reloads * data from cache if necessary. * * As a result, the provided pointer to the cache area is set to its new value. * * The provided increment must be less than SEQREAD_CACHE_SIZE. The reader's * behavior is undefined if the increment exceeds this value. * * @param ptr the incremented pointer * @param inc the number of bytes added to this pointer * @param reader a pointer to the sequential reader * @return The updated pointer value. */ #define seqread_get __SEQREAD_GET void * __SEQREAD_SEEK(__mram_ptr void *mram_addr, seqreader_t *reader); /** * @fn seqread_seek * @brief Set the position of the cache to the supplied MRAM address * * Update automatically the cache if necessary. * * @param mram_addr the new buffer address in MRAM * @param reader a pointer to the sequential reader * @return A ptr to the first byte in cache corresponding to the MRAM address */ #define seqread_seek __SEQREAD_SEEK __mram_ptr void * __SEQREAD_TELL(void *ptr, seqreader_t *reader); /** * @fn seqread_tell * @brief Get the MRAM address corresponding to the supplied ptr in the cache * * @param ptr a pointer in the cache * @param reader a pointer to the sequential reader * @return A ptr to the MRAM address corresponding to the supplied pointer in the cache */ #define seqread_tell __SEQREAD_TELL #endif /* DPUSYSCORE_SEQREAD_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread.inc ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #define PAGE_SIZE (SEQREAD_CACHE_SIZE) #define PAGE_ALLOC_SIZE (2 * PAGE_SIZE) #define PAGE_OFF_MASK (PAGE_SIZE - 1) #define PAGE_IDX_MASK (~PAGE_OFF_MASK) #define MRAM_READ_PAGE(from, to) mram_read((__mram_ptr void *)(from), (void *)(to), PAGE_ALLOC_SIZE) extern void * mem_alloc_nolock(size_t size); ATOMIC_BIT_EXTERN(__heap_pointer); seqreader_buffer_t __SEQREAD_ALLOC(void) { ATOMIC_BIT_ACQUIRE(__heap_pointer); unsigned int heap_pointer = __HEAP_POINTER; seqreader_buffer_t pointer = (seqreader_buffer_t)((heap_pointer + PAGE_OFF_MASK) & PAGE_IDX_MASK); size_t size = pointer + PAGE_ALLOC_SIZE - heap_pointer; /* We already compute the return pointer * mem_alloc_nolock is only used to really reserve the memory area in the heap */ mem_alloc_nolock(size); ATOMIC_BIT_RELEASE(__heap_pointer); return pointer; } void * __SEQREAD_INIT(seqreader_buffer_t cache, __mram_ptr void *mram_addr, seqreader_t *reader) { reader->wram_cache = cache; reader->mram_addr = (uintptr_t)(1 << __DPU_MRAM_SIZE_LOG2); return __SEQREAD_SEEK(mram_addr, reader); } void * __SEQREAD_GET(void *ptr, uint32_t inc, seqreader_t *reader) { return (void *)__builtin_dpu_seqread_get((uintptr_t)ptr, inc, reader, PAGE_SIZE); } void * __SEQREAD_SEEK(__mram_ptr void *mram_addr, seqreader_t *reader) { uintptr_t target_addr = (uintptr_t)mram_addr; uintptr_t current_addr = (uintptr_t)reader->mram_addr; uintptr_t wram_cache = (uintptr_t)reader->wram_cache; uintptr_t mram_offset = target_addr - current_addr; if ((mram_offset & PAGE_IDX_MASK) != 0) { uintptr_t target_addr_idx_page = target_addr & PAGE_IDX_MASK; MRAM_READ_PAGE(target_addr_idx_page, wram_cache); mram_offset = target_addr & PAGE_OFF_MASK; reader->mram_addr = target_addr_idx_page; } return (void *)(mram_offset + wram_cache); } __mram_ptr void * __SEQREAD_TELL(void *ptr, seqreader_t *reader) { return (__mram_ptr void *)((uintptr_t)reader->mram_addr + ((uintptr_t)ptr & PAGE_OFF_MASK)); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread1024.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 1024 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread128.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 128 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread256.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 256 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread32.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 32 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread512.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 512 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/seqread64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #define SEQREAD_CACHE_SIZE 64 #include ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/soft_cache.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include unsigned long __sw_cache_buffer[NR_THREADS] __dma_aligned __used; ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/soft_cache.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SOFT_CACHE_H #define DPUSYSCORE_SOFT_CACHE_H /** * @file soft_cache.h * @brief Software cache * * The software cache mechanism emulates a hardware cache to transparently load and store data from and to the * MRAM. * * This mechanism is quite slow, thus would only be used during the development process, to simplify the code. * * This module defines: * * - A procedure to start the software cache, by creating a "virtual TLB" in the system, along with an area in WRAM to contain * the cached MRAM pages * - A procedure to flush the cache at the end of an execution, ensuring that the data in MRAM are consistent with the cached * data * - The special C directive "__mram", used to declare a pointer directly representing a buffer in MRAM. * * An MRAM pointer is mapped by the caching system. As a consequence, any access to data within this buffer is trapped * by a cache load or store procedure, transparently performing the required memory transactions to fetch and write back * the data. * */ #include #endif /* DPUSYSCORE_SOFT_CACHE_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/subdf3.c ================================================ //===-- lib/adddf3.c - Double-precision subtraction ---------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements double-precision soft-float subtraction with the // IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define DOUBLE_PRECISION #include "fp_lib.h" // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t __subdf3(fp_t a, fp_t b) { return __adddf3(a, fromRep(toRep(b) ^ signBit)); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_dsub(fp_t a, fp_t b) { return __subdf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/subsf3.c ================================================ //===-- lib/subsf3.c - Single-precision subtraction ---------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements single-precision soft-float subtraction with the // IEEE-754 default rounding (to nearest, ties to even). // //===----------------------------------------------------------------------===// #define SINGLE_PRECISION #include "fp_lib.h" // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t __subsf3(fp_t a, fp_t b) { return __addsf3(a, fromRep(toRep(b) ^ signBit)); } #if defined(__ARM_EABI__) AEABI_RTABI fp_t __aeabi_fsub(fp_t a, fp_t b) { return __subsf3(a, b); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/subvdi3.c ================================================ /* ===-- subvdi3.c - Implement __subvdi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __subvdi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a - b */ /* Effects: aborts if a - b overflows */ COMPILER_RT_ABI di_int __subvdi3(di_int a, di_int b) { di_int s = (du_int)a - (du_int)b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/subvsi3.c ================================================ /* ===-- subvsi3.c - Implement __subvsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __subvsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a - b */ /* Effects: aborts if a - b overflows */ COMPILER_RT_ABI si_int __subvsi3(si_int a, si_int b) { si_int s = (su_int)a - (su_int)b; if (b >= 0) { if (s > a) compilerrt_abort(); } else { if (s <= a) compilerrt_abort(); } return s; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/sysdef.h ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef DPUSYSCORE_SYSDEF_H #define DPUSYSCORE_SYSDEF_H /** * @file sysdef.h * @brief Provides useful system abstractions. */ /** * @typedef thread_id_t * @brief A unique runtime number. */ typedef unsigned int thread_id_t; /** * @typedef sysname_t * @brief A system name. * * Used to name system structures, like mutexes, semaphores, meetpoints, etc... In practice, system names * are integers, representing a unique identifier for the given type of structure. */ typedef unsigned int sysname_t; #endif /* DPUSYSCORE_SYSDEF_H */ ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/truncdfhf2.c ================================================ //===-- lib/truncdfhf2.c - double -> half conversion --------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_DOUBLE #define DST_HALF #include "fp_trunc_impl.inc" COMPILER_RT_ABI uint16_t __truncdfhf2(double a) { return __truncXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI uint16_t __aeabi_d2h(double a) { return __truncdfhf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/truncdfsf2.c ================================================ //===-- lib/truncdfsf2.c - double -> single conversion ------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_DOUBLE #define DST_SINGLE #include "fp_trunc_impl.inc" COMPILER_RT_ABI float __truncdfsf2(double a) { return __truncXfYf2__(a); } #if defined(__ARM_EABI__) AEABI_RTABI float __aeabi_d2f(double a) { return __truncdfsf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/truncsfhf2.c ================================================ //===-- lib/truncsfhf2.c - single -> half conversion --------------*- C -*-===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE_LLVM.TXT for details. // //===----------------------------------------------------------------------===// #define SRC_SINGLE #define DST_HALF #include "fp_trunc_impl.inc" // Use a forwarding definition and noinline to implement a poor man's alias, // as there isn't a good cross-platform way of defining one. COMPILER_RT_ABI NOINLINE uint16_t __truncsfhf2(float a) { return __truncXfYf2__(a); } COMPILER_RT_ABI uint16_t __gnu_f2h_ieee(float a) { return __truncsfhf2(a); } #if defined(__ARM_EABI__) AEABI_RTABI uint16_t __aeabi_f2h(float a) { return __truncsfhf2(a); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/ucmpdi2.c ================================================ /* ===-- ucmpdi2.c - Implement __ucmpdi2 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __ucmpdi2 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 */ COMPILER_RT_ABI si_int __ucmpdi2(du_int a, du_int b) { udwords x; x.all = a; udwords y; y.all = b; if (x.s.high < y.s.high) return 0; if (x.s.high > y.s.high) return 2; if (x.s.low < y.s.low) return 0; if (x.s.low > y.s.low) return 2; return 1; } #ifdef __ARM_EABI__ /* Returns: if (a < b) returns -1 * if (a == b) returns 0 * if (a > b) returns 1 */ COMPILER_RT_ABI si_int __aeabi_ulcmp(di_int a, di_int b) { return __ucmpdi2(a, b) - 1; } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/udiv64.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 multiplication unsigned division. */ #include #include static unsigned int __clz__(uint64_t x) { return __builtin_clzl(x); } uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder) { uint64_t dxo = dividend, dxe = 0; if (divider == 0) goto division_by_zero; if (divider > dividend) { if (ask_remainder == 0) return 0; else return dividend; } // Mimic the div_step. /// div_step functionality: // if (Dxo >= (Ra<< #u5)) { // Dxo = Dxo - (Ra<< #u5); // Dxe = (Dxe << 1) | 1; // } else { // Dxe = Dxe << 1; // } int dividerl0 = __clz__(divider), dividendl0 = __clz__(dividend); int i = dividerl0 - dividendl0; for (; i >= 0; i--) { uint64_t pivot = ((uint64_t)divider << i); if (dxo >= pivot) { dxo = dxo - pivot; dxe = ((uint64_t)dxe << 1) | 1L; } else { dxe = (uint64_t)dxe << 1; } } if (ask_remainder == 1) return dxo; else return dxe; division_by_zero: __asm__ volatile("fault " __STR(__FAULT_DIVISION_BY_ZERO__)); unreachable(); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/udivdi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 unsigned division. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); uint64_t __udivdi3(uint64_t dividend, uint64_t divider) { return __udiv64(dividend, divider, 0); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/udivmodsi4.c ================================================ /*===-- udivmodsi4.c - Implement __udivmodsi4 ------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __udivmodsi4 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b, *rem = a % b */ extern unsigned long __udiv32(unsigned int, unsigned int); COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem) { unsigned long res = __udiv32(a, b); *rem = (unsigned int)res; return (unsigned int)(res >> 32); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/udivsi3.c ================================================ /* ===-- udivsi3.c - Implement __udivsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __udivsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a / b */ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ /* This function should not call __divsi3! */ COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d) { const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; su_int q; su_int r; unsigned sr; /* special cases */ if (d == 0) return 0; /* ?! */ if (n == 0) return 0; sr = __builtin_clz(d) - __builtin_clz(n); /* 0 <= sr <= n_uword_bits - 1 or sr large */ if (sr > n_uword_bits - 1) /* d > r */ return 0; if (sr == n_uword_bits - 1) /* d == 1 */ return n; ++sr; /* 1 <= sr <= n_uword_bits - 1 */ /* Not a special case */ q = n << (n_uword_bits - sr); r = n >> sr; su_int carry = 0; for (; sr > 0; --sr) { /* r:q = ((r:q) << 1) | carry */ r = (r << 1) | (q >> (n_uword_bits - 1)); q = (q << 1) | carry; /* carry = 0; * if (r.all >= d.all) * { * r.all -= d.all; * carry = 1; * } */ const si_int s = (si_int)(d - r - 1) >> (n_uword_bits - 1); carry = s & 1; r -= d & s; } q = (q << 1) | carry; return q; } #if defined(__ARM_EABI__) AEABI_RTABI su_int __aeabi_uidiv(su_int n, su_int d) { return __udivsi3(n, d); } #endif ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/umoddi3.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* * 64x64 unsigned remainder. * * This is the actual libcall implementation, as requested by the compiler. */ #include extern uint64_t __udiv64(uint64_t dividend, uint64_t divider, int ask_remainder); uint64_t __umoddi3(uint64_t dividend, uint64_t divider) { return __udiv64(dividend, divider, 1); } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/umodsi3.c ================================================ /* ===-- umodsi3.c - Implement __umodsi3 -----------------------------------=== * * The LLVM Compiler Infrastructure * * This file is dual licensed under the MIT and the University of Illinois Open * Source Licenses. See LICENSE_LLVM.TXT for details. * * ===----------------------------------------------------------------------=== * * This file implements __umodsi3 for the compiler_rt library. * * ===----------------------------------------------------------------------=== */ #include "int_lib.h" /* Returns: a % b */ extern unsigned long __udiv32(unsigned int, unsigned int); COMPILER_RT_ABI su_int __umodsi3(su_int a, su_int b) { unsigned long res = __udiv32(a, b); return (unsigned int)res; } ================================================ FILE: golang_vm/uPIMulator/sdk/syslib/waitqueue.c ================================================ /* Copyright 2020 UPMEM. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include unsigned char __attribute__((used)) __sys_wq_table[NR_THREADS] = { [0 ...(NR_THREADS - 1)] = __EMPTY_WAIT_QUEUE }; ================================================ FILE: golang_vm/uPIMulator/src/device/abi/intermediate.go ================================================ package abi import ( "uPIMulator/src/encoding" ) type Immediate struct { representation Representation value int64 word *Word } func (this *Immediate) Init(representation Representation, width int, value int64) { this.representation = representation this.value = value this.word = new(Word) this.word.Init(width) this.word.SetValue(value) } func (this *Immediate) Representation() Representation { return this.representation } func (this *Immediate) Width() int { return this.word.Width() } func (this *Immediate) Bit(pos int) bool { return this.word.Bit(pos) } func (this *Immediate) BitSlice(begin int, end int) int64 { return this.word.BitSlice(this.representation, begin, end) } func (this *Immediate) Value() int64 { return this.value } func (this *Immediate) ToByteStream() *encoding.ByteStream { return this.word.ToByteStream() } ================================================ FILE: golang_vm/uPIMulator/src/device/abi/word.go ================================================ package abi import ( "errors" "uPIMulator/src/encoding" ) type Representation int const ( UNSIGNED Representation = iota SIGNED ) type Word struct { bits []bool } func (this *Word) Init(width int) { if width <= 0 { err := errors.New("width <= 0") panic(err) } this.bits = make([]bool, width) } func (this *Word) Width() int { return len(this.bits) } func (this *Word) Size() int { if this.Width()%8 != 0 { err := errors.New("width is not a multiple of 8") panic(err) } return this.Width() / 8 } func (this *Word) SignBit() bool { return this.bits[this.Width()-1] } func (this *Word) Bit(pos int) bool { return this.bits[pos] } func (this *Word) SetBit(pos int) { this.bits[pos] = true } func (this *Word) ClearBit(pos int) { this.bits[pos] = false } func (this *Word) BitSlice(representation Representation, begin int, end int) int64 { this.VerifySlice(begin, end) slice_width := end - begin value := int64(0) for i := 0; i < slice_width; i++ { if this.Bit(begin + i) { if representation == SIGNED && i == slice_width-1 { value -= this.Pow2(i) } else { value += this.Pow2(i) } } } return value } func (this *Word) SetBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value >= 0 { this.SetPositiveBitSlice(begin, end, value) } else { this.SetNegativeBitSlice(begin, end, value) } } func (this *Word) Value(representation Representation) int64 { return this.BitSlice(representation, 0, this.Width()) } func (this *Word) SetValue(value int64) { this.SetBitSlice(0, this.Width(), value) } func (this *Word) ToByteStream() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := 0; i < this.Size(); i++ { begin := 8 * i end := begin + 8 value := uint8(this.BitSlice(UNSIGNED, begin, end)) byte_stream.Append(value) } return byte_stream } func (this *Word) FromByteStream(byte_stream *encoding.ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { begin := int(8 * i) end := int(begin + 8) value := int64(byte_stream.Get(int(i))) this.SetBitSlice(begin, end, value) } } func (this *Word) VerifySlice(begin int, end int) { if begin < 0 { err := errors.New("begin < 0") panic(err) } if begin >= end { err := errors.New("begin >= end") panic(err) } if end > this.Width() { err := errors.New("end > width") panic(err) } if end-begin > 64 { err := errors.New("end - begin >= 64") panic(err) } } func (this *Word) Pow2(exponent int) int64 { value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } func (this *Word) SetPositiveBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value < 0 { err := errors.New("value < 0") panic(err) } slice_width := end - begin for i := 0; i < slice_width; i++ { if value%2 == 1 { this.SetBit(begin + i) } else { this.ClearBit(begin + i) } value /= 2 } if value != 0 { err := errors.New("value != 0") panic(err) } } func (this *Word) SetNegativeBitSlice(begin int, end int, value int64) { this.VerifySlice(begin, end) if value >= 0 { err := errors.New("value >= 0") panic(err) } this.SetBit(end - 1) if begin+1 < end { slice_width := end - begin value += this.Pow2(slice_width - 1) this.SetPositiveBitSlice(begin, end-1, value) } } ================================================ FILE: golang_vm/uPIMulator/src/device/compiler/compiler.go ================================================ package compiler import ( "os/exec" "path/filepath" "strconv" "uPIMulator/src/misc" ) type Compiler struct { root_dirpath string benchmark string num_dpus int num_tasklets int } func (this *Compiler) Init(command_line_parser *misc.CommandLineParser) { this.root_dirpath = command_line_parser.StringParameter("root_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.Build() } func (this *Compiler) Build() { docker_dirpath := filepath.Join(this.root_dirpath, "docker") command := exec.Command("docker", "build", "-t", "bongjoonhyun/upimulator", docker_dirpath) err := command.Run() if err != nil { panic(err) } } func (this *Compiler) Compile() { this.CompileBenchmark() this.CompileSdk() } func (this *Compiler) CompileBenchmark() { command := exec.Command( "docker", "run", "--privileged", "--rm", "-v", this.root_dirpath+":/root/uPIMulator", "bongjoonhyun/upimulator", "python3", "/root/uPIMulator/benchmark/build.py", "--num_dpus", strconv.Itoa(this.num_dpus), "--num_tasklets", strconv.Itoa(this.num_tasklets), ) err := command.Run() if err != nil { panic(err) } } func (this *Compiler) CompileSdk() { command := exec.Command( "docker", "run", "--privileged", "--rm", "-v", this.root_dirpath+":/root/uPIMulator", "bongjoonhyun/upimulator", "python3", "/root/uPIMulator/sdk/build.py", "--num_tasklets", strconv.Itoa(this.num_tasklets), ) err := command.Run() if err != nil { panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/core/job.go ================================================ package core type Job interface { Execute() } ================================================ FILE: golang_vm/uPIMulator/src/device/core/thread_pool.go ================================================ package core import ( "sync" ) type ThreadPool struct { jobs []Job wg sync.WaitGroup } func (this *ThreadPool) Init() { this.jobs = make([]Job, 0) } func (this *ThreadPool) Enque(job Job) { this.wg.Add(1) this.jobs = append(this.jobs, job) } func (this *ThreadPool) Start() { for _, job := range this.jobs { go this.Dispatch(job) } this.wg.Wait() } func (this *ThreadPool) Dispatch(job Job) { defer this.wg.Done() job.Execute() } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/analyze_liveness_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/logic" ) type AnalyzeLivenessJob struct { relocatable *kernel.Relocatable } func (this *AnalyzeLivenessJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *AnalyzeLivenessJob) Execute() { fmt.Printf("Analyzing the liveness of %s...\n", this.relocatable.Path()) liveness_analyzer := new(logic.LivenessAnalyzer) liveness_analyzer.Init() liveness := liveness_analyzer.Analyze(this.relocatable) this.relocatable.SetLiveness(liveness) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/ascii_directive.go ================================================ package directive import ( "uPIMulator/src/encoding" ) type AsciiDirective struct { characters string } func (this *AsciiDirective) Init(characters string) { this.characters = characters } func (this *AsciiDirective) Characters() string { return this.characters } func (this *AsciiDirective) Size() int64 { return int64(len(this.characters)) } func (this *AsciiDirective) Encode() *encoding.ByteStream { ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() return ascii_encoder.Encode(this.characters) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/asciz_directive.go ================================================ package directive import ( "uPIMulator/src/encoding" ) type AscizDirective struct { characters string } func (this *AscizDirective) Init(characters string) { this.characters = characters } func (this *AscizDirective) Characters() string { return this.characters } func (this *AscizDirective) Size() int64 { return int64(len(this.characters)) + 1 } func (this *AscizDirective) Encode() *encoding.ByteStream { ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() return ascii_encoder.Encode(this.characters + ascii_encoder.Unknown()) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/byte_directive.go ================================================ package directive import ( "uPIMulator/src/device/abi" "uPIMulator/src/encoding" ) type ByteDirective struct { immediate *abi.Immediate } func (this *ByteDirective) Init(value int64) { this.immediate = new(abi.Immediate) this.immediate.Init(abi.UNSIGNED, 8*int(this.Size()), value) } func (this *ByteDirective) Size() int64 { return 1 } func (this *ByteDirective) Immediate() *abi.Immediate { return this.immediate } func (this *ByteDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/long_directive.go ================================================ package directive import ( "uPIMulator/src/device/abi" "uPIMulator/src/encoding" ) type LongDirective struct { immediate *abi.Immediate } func (this *LongDirective) Init(value int64) { this.immediate = new(abi.Immediate) this.immediate.Init(abi.UNSIGNED, 8*int(this.Size()), value) } func (this *LongDirective) Size() int64 { return 4 } func (this *LongDirective) Immediate() *abi.Immediate { return this.immediate } func (this *LongDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/quad_directive.go ================================================ package directive import ( "uPIMulator/src/device/abi" "uPIMulator/src/encoding" ) type QuadDirective struct { immediate *abi.Immediate } func (this *QuadDirective) Init(value int64) { this.immediate = new(abi.Immediate) this.immediate.Init(abi.UNSIGNED, 8*int(this.Size()), value) } func (this *QuadDirective) Size() int64 { return 8 } func (this *QuadDirective) Immediate() *abi.Immediate { return this.immediate } func (this *QuadDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/short_directive.go ================================================ package directive import ( "uPIMulator/src/device/abi" "uPIMulator/src/encoding" ) type ShortDirective struct { immediate *abi.Immediate } func (this *ShortDirective) Init(value int64) { this.immediate = new(abi.Immediate) this.immediate.Init(abi.UNSIGNED, 8*int(this.Size()), value) } func (this *ShortDirective) Size() int64 { return 2 } func (this *ShortDirective) Immediate() *abi.Immediate { return this.immediate } func (this *ShortDirective) Encode() *encoding.ByteStream { return this.immediate.ToByteStream() } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/directive/zero_directive.go ================================================ package directive import ( "errors" "uPIMulator/src/device/abi" "uPIMulator/src/encoding" ) type ZeroDirective struct { size int64 immediate *abi.Immediate } func (this *ZeroDirective) Init(size int64, value int64) { if size <= 0 { err := errors.New("size <= 0") panic(err) } this.size = size this.immediate = new(abi.Immediate) this.immediate.Init(abi.UNSIGNED, 8, value) } func (this *ZeroDirective) Size() int64 { return this.size } func (this *ZeroDirective) Immediate() *abi.Immediate { return this.immediate } func (this *ZeroDirective) Encode() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < this.size; i++ { byte_stream.Merge(this.immediate.ToByteStream()) } return byte_stream } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/encodable.go ================================================ package kernel import ( "uPIMulator/src/encoding" ) type Encodable interface { Encode() *encoding.ByteStream } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/executable.go ================================================ package kernel import ( "errors" "fmt" "sort" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Executable struct { name string path string benchmark_relocatable *Relocatable sdk_relocatables map[*Relocatable]bool token_stream *lexer.TokenStream ast *parser.Ast liveness *Liveness sections map[*Section]bool cur_section *Section } func (this *Executable) Init(name string) { this.name = name this.sdk_relocatables = make(map[*Relocatable]bool) this.liveness = new(Liveness) this.liveness.Init() this.sections = make(map[*Section]bool) } func (this *Executable) Name() string { return this.name } func (this *Executable) Path() string { return this.path } func (this *Executable) SetPath(path string) { this.path = path } func (this *Executable) SetBenchmarkRelocatable(relocatable *Relocatable) { this.benchmark_relocatable = relocatable this.UpdateUnresolvedSymbols(relocatable) } func (this *Executable) AddSdkRelocatable(relocatable *Relocatable) { this.sdk_relocatables[relocatable] = true this.UpdateLocalSymbols(relocatable) this.UpdateUnresolvedSymbols(relocatable) } func (this *Executable) TokenStream() *lexer.TokenStream { return this.token_stream } func (this *Executable) SetTokenStream(token_stream *lexer.TokenStream) { this.token_stream = token_stream } func (this *Executable) Ast() *parser.Ast { return this.ast } func (this *Executable) SetAst(ast *parser.Ast) { this.ast = ast } func (this *Executable) Liveness() *Liveness { return this.liveness } func (this *Executable) DumpAssembly() { lines := this.benchmark_relocatable.Lines() for sdk_relocatable, _ := range this.sdk_relocatables { lines = append(lines, sdk_relocatable.Lines()...) } file_dumper := new(misc.FileDumper) file_dumper.Init(this.path) file_dumper.WriteLines(lines) } func (this *Executable) DumpAddresses(path string) { lines := make([]string, 0) for label_name, label_address := range this.Addresses() { line := fmt.Sprintf("%s: %d", label_name, label_address) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpAtomic(path string) { atomic_byte_stream := this.AtomicByteStream() lines := make([]string, 0) for i := int64(0); i < atomic_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", atomic_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpIram(path string) { iram_byte_stream := this.IramByteStream() lines := make([]string, 0) for i := int64(0); i < iram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", iram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpWram(path string) { wram_byte_stream := this.WramByteStream() lines := make([]string, 0) for i := int64(0); i < wram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", wram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) DumpMram(path string) { mram_byte_stream := this.MramByteStream() lines := make([]string, 0) for i := int64(0); i < mram_byte_stream.Size(); i++ { line := fmt.Sprintf("%d", mram_byte_stream.Get(int(i))) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } func (this *Executable) Section(section_name SectionName, name string) *Section { for section, _ := range this.sections { if section.SectionName() == section_name && section.Name() == name { return section } } return nil } func (this *Executable) Sections(section_name SectionName) map[*Section]bool { sections := make(map[*Section]bool) for section, _ := range this.sections { if section.SectionName() == section_name { sections[section] = true } } return sections } func (this *Executable) AddSection( section_name SectionName, name string, section_flags map[SectionFlag]bool, section_type SectionType, ) { if this.Section(section_name, name) == nil { section := new(Section) section.Init(section_name, name, section_flags, section_type) this.sections[section] = true } } func (this *Executable) CurSection() *Section { return this.cur_section } func (this *Executable) CheckoutSection(section_name SectionName, name string) { if section := this.Section(section_name, name); section != nil { this.cur_section = section } else { err := errors.New("section is not found") panic(err) } } func (this *Executable) Label(label_name string) *Label { var label *Label = nil for section, _ := range this.sections { section_label := section.Label(label_name) if section_label != nil { if label != nil { err := errors.New("labels are duplicated") panic(err) } label = section_label } } return label } func (this *Executable) Addresses() map[string]int64 { addresses := make(map[string]int64) for section, _ := range this.sections { for _, label := range section.Labels() { addresses[label.Name()] = label.Address() } } return addresses } func (this *Executable) AtomicByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() atomic_sections := this.Sort( config_loader.AtomicOffset(), config_loader.AtomicOffset()+config_loader.AtomicSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, atomic_section := range atomic_sections { byte_stream.Merge(atomic_section.ToByteStream()) } return byte_stream } func (this *Executable) IramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_sections := this.Sort( config_loader.IramOffset(), config_loader.IramOffset()+config_loader.IramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, iram_section := range iram_sections { byte_stream.Merge(iram_section.ToByteStream()) } return byte_stream } func (this *Executable) WramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() wram_sections := this.Sort( config_loader.WramOffset(), config_loader.WramOffset()+config_loader.WramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, wram_section := range wram_sections { byte_stream.Merge(wram_section.ToByteStream()) } return byte_stream } func (this *Executable) MramByteStream() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_sections := this.Sort( config_loader.MramOffset(), config_loader.MramOffset()+config_loader.MramSize(), ) byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, mram_section := range mram_sections { byte_stream.Merge(mram_section.ToByteStream()) } return byte_stream } func (this *Executable) UpdateLocalSymbols(relocatable *Relocatable) { for old_name, _ := range relocatable.Liveness().LocalSymbols() { new_name := relocatable.Name() + "." + old_name relocatable.RenameLocalSymbol(old_name, new_name) } } func (this *Executable) UpdateUnresolvedSymbols(relocatable *Relocatable) { for def, _ := range relocatable.Liveness().Defs() { this.liveness.AddDef(def) } for use, _ := range relocatable.Liveness().Uses() { this.liveness.AddUse(use) } for global_symbol, _ := range relocatable.Liveness().GlobalSymbols() { this.liveness.AddGlobalSymbol(global_symbol) } } func (this *Executable) Sort(begin_address int64, end_address int64) []*Section { sections := make([]*Section, 0) for section, _ := range this.sections { address := section.Address() if begin_address <= address && address < end_address { sections = append(sections, section) } } sort_fn := func(i int, j int) bool { return sections[i].Address() < sections[j].Address() } sort.Slice(sections, sort_fn) return sections } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/acquire_cc.go ================================================ package cc import ( "errors" ) type AcquireCc struct { condition Condition } func (this *AcquireCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *AcquireCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/add_nz_cc.go ================================================ package cc import ( "errors" ) type AddNzCc struct { condition Condition } func (this *AddNzCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, NC5: true, NC6: true, NC7: true, NC8: true, NC9: true, NC10: true, NC11: true, NC12: true, NC13: true, NC14: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *AddNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/boot_cc.go ================================================ package cc import ( "errors" ) type BootCc struct { condition Condition } func (this *BootCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *BootCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/cc.go ================================================ package cc type Condition int const ( TRUE Condition = iota FALSE Z NZ E O PL MI OV NOV C NC SZ SNZ SPL SMI SO SE NC5 NC6 NC7 NC8 NC9 NC10 NC11 NC12 NC13 NC14 MAX NMAX SH32 NSH32 EQ NEQ LTU LEU GTU GEU LTS LES GTS GES XZ XNZ XLEU XGTU XLES XGTS SMALL LARGE ) type Cc interface { Condition() Condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/const_cc_ge0.go ================================================ package cc import ( "errors" ) type ConstCcGe0 struct { condition Condition } func (this *ConstCcGe0) Init(condition Condition) { conditions := map[Condition]bool{ PL: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcGe0) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/const_cc_geu.go ================================================ package cc import ( "errors" ) type ConstCcGeu struct { condition Condition } func (this *ConstCcGeu) Init(condition Condition) { conditions := map[Condition]bool{ GEU: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcGeu) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/const_cc_zero.go ================================================ package cc import ( "errors" ) type ConstCcZero struct { condition Condition } func (this *ConstCcZero) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ConstCcZero) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/count_nz_cc.go ================================================ package cc import ( "errors" ) type CountNzCc struct { condition Condition } func (this *CountNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, MAX: true, NMAX: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *CountNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/div_cc.go ================================================ package cc import ( "errors" ) type DivCc struct { condition Condition } func (this *DivCc) Init(condition Condition) { conditions := map[Condition]bool{ SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *DivCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/div_nz_cc.go ================================================ package cc import ( "errors" ) type DivNzCc struct { condition Condition } func (this *DivNzCc) Init(condition Condition) { conditions := map[Condition]bool{ SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *DivNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/ext_sub_set_cc.go ================================================ package cc import ( "errors" ) type ExtSubSetCc struct { condition Condition } func (this *ExtSubSetCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, EQ: true, NEQ: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, GES: true, GEU: true, GTS: true, GTU: true, LES: true, LEU: true, LTS: true, LTU: true, XGTS: true, XGTU: true, XLES: true, XLEU: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ExtSubSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/false_cc.go ================================================ package cc import ( "errors" ) type FalseCc struct { condition Condition } func (this *FalseCc) Init(condition Condition) { conditions := map[Condition]bool{ FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *FalseCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/imm_shift_nz_cc.go ================================================ package cc import ( "errors" ) type ImmShiftNzCc struct { condition Condition } func (this *ImmShiftNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, E: true, O: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, SE: true, SO: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ImmShiftNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/log_nz_cc.go ================================================ package cc import ( "errors" ) type LogNzCc struct { condition Condition } func (this *LogNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, PL: true, MI: true, SZ: true, SNZ: true, SPL: true, SMI: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *LogNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/log_set_cc.go ================================================ package cc import ( "errors" ) type LogSetCc struct { condition Condition } func (this *LogSetCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *LogSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/mul_nz_cc.go ================================================ package cc import ( "errors" ) type MulNzCc struct { condition Condition } func (this *MulNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, SZ: true, SNZ: true, SPL: true, SMI: true, LARGE: true, SMALL: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *MulNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/no_cc.go ================================================ package cc import ( "errors" ) type NoCc struct { condition Condition } func (this *NoCc) Init(condition Condition) { conditions := map[Condition]bool{} if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *NoCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/release_cc.go ================================================ package cc import ( "errors" ) type ReleaseCc struct { condition Condition } func (this *ReleaseCc) Init(condition Condition) { conditions := map[Condition]bool{ NZ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ReleaseCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/shift_nz_cc.go ================================================ package cc import ( "errors" ) type ShiftNzCc struct { condition Condition } func (this *ShiftNzCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, E: true, O: true, PL: true, MI: true, SZ: true, SNZ: true, SE: true, SO: true, SPL: true, SMI: true, SH32: true, NSH32: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *ShiftNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/sub_nz_cc.go ================================================ package cc import ( "errors" ) type SubNzCc struct { condition Condition } func (this *SubNzCc) Init(condition Condition) { conditions := map[Condition]bool{ C: true, NC: true, Z: true, NZ: true, XZ: true, XNZ: true, OV: true, NOV: true, MI: true, PL: true, EQ: true, NEQ: true, SPL: true, SMI: true, GES: true, GEU: true, GTS: true, GTU: true, LES: true, LEU: true, LTS: true, LTU: true, XGTS: true, XGTU: true, XLES: true, XLEU: true, TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *SubNzCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/sub_set_cc.go ================================================ package cc import ( "errors" ) type SubSetCc struct { condition Condition } func (this *SubSetCc) Init(condition Condition) { conditions := map[Condition]bool{ Z: true, NZ: true, XZ: true, XNZ: true, EQ: true, NEQ: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *SubSetCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/true_cc.go ================================================ package cc import ( "errors" ) type TrueCc struct { condition Condition } func (this *TrueCc) Init(condition Condition) { conditions := map[Condition]bool{ TRUE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *TrueCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/cc/true_false_cc.go ================================================ package cc import ( "errors" ) type TrueFalseCc struct { condition Condition } func (this *TrueFalseCc) Init(condition Condition) { conditions := map[Condition]bool{ TRUE: true, FALSE: true, } if _, found := conditions[condition]; !found { err := errors.New("condition is not allowed") panic(err) } this.condition = condition } func (this *TrueFalseCc) Condition() Condition { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/endian.go ================================================ package instruction type Endian int const ( LITTLE Endian = iota BIG ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/exception.go ================================================ package instruction type Exception int const ( MEMORY_FAULT Exception = iota DMA_FAULT HEAP_FULL DIVISION_BY_ZERO ASSERT HALT PRINT_OVERFLOW ALREADY_PROFILING NOT_PROFILING ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/flag.go ================================================ package instruction type Flag int const ( ZERO Flag = iota CARRY ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/instruction.go ================================================ package instruction import ( "errors" "math" "strconv" "uPIMulator/src/device/abi" "uPIMulator/src/device/linker/kernel/instruction/cc" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Instruction struct { op_code OpCode suffix Suffix rc *reg_descriptor.GpRegDescriptor ra *reg_descriptor.SrcRegDescriptor rb *reg_descriptor.SrcRegDescriptor dc *reg_descriptor.PairRegDescriptor db *reg_descriptor.PairRegDescriptor condition *cc.Condition imm *abi.Immediate off *abi.Immediate pc *abi.Immediate endian *Endian } func (this *Instruction) InitRici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RiciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } this.op_code = op_code this.suffix = RICI this.ra = ra this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 16, imm) this.condition = new(cc.Condition) *this.condition = condition config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRri( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } this.op_code = op_code this.suffix = RRI this.rc = rc this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) InitRric( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } this.op_code = op_code this.suffix = RRIC this.rc = rc this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) ext_sub_setcc := new(cc.ExtSubSetCc) ext_sub_setcc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_setcc.Condition() } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } } func (this *Instruction) InitRrici( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } this.op_code = op_code this.suffix = RRICI this.rc = rc this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRrif( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } this.op_code = op_code this.suffix = RRIF this.rc = rc this.ra = ra this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) false_cc := new(cc.FalseCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitRrr( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } this.op_code = op_code this.suffix = RRR this.rc = rc this.ra = ra this.rb = rb } func (this *Instruction) InitRrrc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } this.op_code = op_code this.suffix = RRRC this.rc = rc this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitRrrci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } this.op_code = op_code this.suffix = RRRCI this.rc = rc this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZri(op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } this.op_code = op_code this.suffix = ZRI this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 28, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) InitZric( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } this.op_code = op_code this.suffix = ZRIC this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) ext_sub_setcc := new(cc.ExtSubSetCc) ext_sub_setcc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_setcc.Condition() } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } } func (this *Instruction) InitZrici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } this.op_code = op_code this.suffix = ZRICI this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZrif( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } this.op_code = op_code this.suffix = ZRIF this.ra = ra this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) false_cc := new(cc.LogSetCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitZrr( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } this.op_code = op_code this.suffix = ZRR this.ra = ra this.rb = rb } func (this *Instruction) InitZrrc( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } this.op_code = op_code this.suffix = ZRRC this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitZrrci( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } this.op_code = op_code this.suffix = ZRRCI this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRri( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if suffix != S_RRI && suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rri_op_code := this.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid S_RRI nor U_RRI op code") panic(err) } } func (this *Instruction) InitSRric( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RricOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if suffix != S_RRIC && suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rric_op_code := this.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[op_code]; is_asr_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid S_RRI nor U_RRI op code") panic(err) } } func (this *Instruction) InitSRrici( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if suffix != S_RRICI && suffix != U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_add_rrici_op_code := this.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) imm_shift_nz_cc := new(cc.ImmShiftNzCc) imm_shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = imm_shift_nz_cc.Condition() } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRrif( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, ) { if _, found := this.RrifOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if suffix != S_RRIF && suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) false_cc := new(cc.FalseCc) false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = false_cc.Condition() } func (this *Instruction) InitSRrr( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if suffix != S_RRR && suffix != U_RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb } func (this *Instruction) InitSRrrc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if suffix != S_RRRC && suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb if _, is_add_rrrc_op_code := this.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } else if _, is_rsub_rrrc_op_code := this.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } else if _, is_sub_rrrc_op_code := this.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { ext_sub_set_cc := new(cc.ExtSubSetCc) ext_sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = ext_sub_set_cc.Condition() } else { err := errors.New("op code is not a valid RRRC op code") panic(err) } } func (this *Instruction) InitSRrrci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if suffix != S_RRRCI && suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb if _, is_add_rrrci_op_code := this.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { add_nz_cc := new(cc.AddNzCc) add_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = add_nz_cc.Condition() } else if _, is_and_rrrci_op_code := this.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_asr_rrrci_op_code := this.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { shift_nz_cc := new(cc.ShiftNzCc) shift_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = shift_nz_cc.Condition() } else if _, is_mul_rrrci_op_code := this.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { mul_nz_cc := new(cc.MulNzCc) mul_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = mul_nz_cc.Condition() } else if _, is_rsub_rrrci_op_code := this.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() } else { err := errors.New("op code is not a valid RRRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRr( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } this.op_code = op_code this.suffix = RR this.rc = rc this.ra = ra } func (this *Instruction) InitRrc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } this.op_code = op_code this.suffix = RRC this.rc = rc this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitRrci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } this.op_code = op_code this.suffix = RRCI this.rc = rc this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZr(op_code OpCode, ra *reg_descriptor.SrcRegDescriptor) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } this.op_code = op_code this.suffix = ZR this.ra = ra } func (this *Instruction) InitZrc( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } this.op_code = op_code this.suffix = ZRC this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitZrci( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } this.op_code = op_code this.suffix = ZRCI this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRr( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RrOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if suffix != S_RR && suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra } func (this *Instruction) InitSRrc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RrcOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if suffix != S_RRC && suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra log_set_cc := new(cc.LogSetCc) log_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_set_cc.Condition() } func (this *Instruction) InitSRrci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RrciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if suffix != S_RRCI && suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra if _, is_cao_rrci_op_code := this.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { count_nz_cc := new(cc.CountNzCc) count_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = count_nz_cc.Condition() } else if _, is_extsb_rrci_op_code := this.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { log_nz_cc := new(cc.LogNzCc) log_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = log_nz_cc.Condition() } else if _, is_time_cfg_rrci_op_code := this.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitDrdici( op_code OpCode, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, db *reg_descriptor.PairRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.DrdiciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } this.op_code = op_code this.suffix = DRDICI this.dc = dc this.ra = ra this.db = db this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) if _, is_div_step_drdici_op_code := this.DivStepDrdiciOpCodes()[op_code]; is_div_step_drdici_op_code { div_cc := new(cc.DivCc) div_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_cc.Condition() } else if _, is_mul_step_drdici_op_code := this.MulStepDrdiciOpCodes()[op_code]; is_mul_step_drdici_op_code { boot_cc := new(cc.BootCc) boot_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = boot_cc.Condition() } else { err := errors.New("op code is not a valid RRCI op code") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRrri( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } this.op_code = op_code this.suffix = RRRI this.rc = rc this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) InitRrrici( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } this.op_code = op_code this.suffix = RRRICI this.rc = rc this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZrri( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } this.op_code = op_code this.suffix = ZRRI this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) InitZrrici( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } this.op_code = op_code this.suffix = ZRRICI this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRrri( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.RrriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if suffix != S_RRRI && suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) InitSRrrici( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, condition cc.Condition, pc int64, ) { if _, found := this.RrriciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if suffix != S_RRRICI && suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) div_nz_cc := new(cc.DivNzCc) div_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = div_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitRir( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.RirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } this.op_code = op_code this.suffix = RIR this.rc = rc this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) this.ra = ra } func (this *Instruction) InitRirc( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } this.op_code = op_code this.suffix = RIRC this.rc = rc this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitRirci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } this.op_code = op_code this.suffix = RIRCI this.rc = rc this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZir(op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor) { if _, found := this.RirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } this.op_code = op_code this.suffix = ZIR this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) this.ra = ra } func (this *Instruction) InitZirc( op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } this.op_code = op_code this.suffix = ZIRC this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitZirci( op_code OpCode, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } this.op_code = op_code this.suffix = ZIRCI this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSRirc( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, ) { if _, found := this.RircOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if suffix != S_RIRC && suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) this.ra = ra sub_set_cc := new(cc.SubSetCc) sub_set_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_set_cc.Condition() } func (this *Instruction) InitSRirci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, imm int64, ra *reg_descriptor.SrcRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RirciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if suffix != S_RIRCI && suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) this.ra = ra sub_nz_cc := new(cc.SubNzCc) sub_nz_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = sub_nz_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitR(op_code OpCode, rc *reg_descriptor.GpRegDescriptor) { if _, found := this.ROpCodes()[op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } this.op_code = op_code this.suffix = R this.rc = rc } func (this *Instruction) InitRci( op_code OpCode, rc *reg_descriptor.GpRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } this.op_code = op_code this.suffix = RCI this.rc = rc true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitZ(op_code OpCode) { if _, found := this.ROpCodes()[op_code]; !found && op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } this.op_code = op_code this.suffix = Z } func (this *Instruction) InitZci( op_code OpCode, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } this.op_code = op_code this.suffix = ZCI true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitSR( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, ) { if _, found := this.ROpCodes()[op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if suffix != S_R && suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc } func (this *Instruction) InitSRci( op_code OpCode, suffix Suffix, dc *reg_descriptor.PairRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.RciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if suffix != S_RCI && suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc true_cc := new(cc.TrueCc) true_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitCi(op_code OpCode, condition cc.Condition, pc int64) { if _, found := this.CiOpCodes()[op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } this.op_code = op_code this.suffix = CI boot_cc := new(cc.BootCc) boot_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = boot_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitI(op_code OpCode, imm int64) { if _, found := this.IOpCodes()[op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } this.op_code = op_code this.suffix = I this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } func (this *Instruction) InitDdci( op_code OpCode, dc *reg_descriptor.PairRegDescriptor, db *reg_descriptor.PairRegDescriptor, condition cc.Condition, pc int64, ) { if _, found := this.DdciOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } this.op_code = op_code this.suffix = DDCI this.dc = dc this.db = db true_false_cc := new(cc.TrueFalseCc) true_false_cc.Init(condition) this.condition = new(cc.Condition) *this.condition = true_false_cc.Condition() config_loader := new(misc.ConfigLoader) config_loader.Init() this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, config_loader.AddressWidth(), pc) } func (this *Instruction) InitErri( op_code OpCode, endian Endian, rc *reg_descriptor.GpRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.ErriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } this.op_code = op_code this.suffix = ERRI this.endian = new(Endian) *this.endian = endian this.rc = rc this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) InitSErri( op_code OpCode, suffix Suffix, endian Endian, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.ErriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if suffix != S_ERRI && suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } this.op_code = op_code this.suffix = suffix this.endian = new(Endian) *this.endian = endian this.dc = dc this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) InitEdri( op_code OpCode, endian Endian, dc *reg_descriptor.PairRegDescriptor, ra *reg_descriptor.SrcRegDescriptor, off int64, ) { if _, found := this.EdriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } this.op_code = op_code this.suffix = EDRI this.endian = new(Endian) *this.endian = endian this.dc = dc this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) InitErii( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, imm int64, ) { if _, found := this.EriiOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } this.op_code = op_code this.suffix = ERII this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 16, imm) } func (this *Instruction) InitErir( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, rb *reg_descriptor.SrcRegDescriptor, ) { if _, found := this.ErirOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } this.op_code = op_code this.suffix = ERIR this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) this.rb = rb } func (this *Instruction) InitErid( op_code OpCode, endian Endian, ra *reg_descriptor.SrcRegDescriptor, off int64, db *reg_descriptor.PairRegDescriptor, ) { if _, found := this.EridOpCodes()[op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } this.op_code = op_code this.suffix = ERID this.endian = new(Endian) *this.endian = endian this.ra = ra this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) this.db = db } func (this *Instruction) InitDmaRri( op_code OpCode, ra *reg_descriptor.SrcRegDescriptor, rb *reg_descriptor.SrcRegDescriptor, imm int64, ) { if _, found := this.DmaRriOpCodes()[op_code]; !found { err := errors.New("op code is not a valid DMA RRI op code") panic(err) } this.op_code = op_code this.suffix = DMA_RRI this.ra = ra this.rb = rb this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 8, imm) } func (this *Instruction) OpCode() OpCode { return this.op_code } func (this *Instruction) Suffix() Suffix { return this.suffix } func (this *Instruction) Rc() *reg_descriptor.GpRegDescriptor { return this.rc } func (this *Instruction) Ra() *reg_descriptor.SrcRegDescriptor { return this.ra } func (this *Instruction) Rb() *reg_descriptor.SrcRegDescriptor { return this.rb } func (this *Instruction) Dc() *reg_descriptor.PairRegDescriptor { return this.dc } func (this *Instruction) Db() *reg_descriptor.PairRegDescriptor { return this.db } func (this *Instruction) Condition() cc.Condition { if this.condition == nil { err := errors.New("condition == nil") panic(err) } return *this.condition } func (this *Instruction) Imm() *abi.Immediate { return this.imm } func (this *Instruction) Off() *abi.Immediate { return this.off } func (this *Instruction) Pc() *abi.Immediate { return this.pc } func (this *Instruction) Endian() Endian { if this.endian == nil { err := errors.New("endian == nil") panic(err) } return *this.endian } func (this *Instruction) Encode() *encoding.ByteStream { config_loader := new(misc.ConfigLoader) config_loader.Init() word_ := new(abi.Word) word_.Init(config_loader.IramDataWidth()) this.EncodeOpCode(word_) this.EncodeSuffix(word_) if this.suffix == RICI { this.EncodeRici(word_) } else if this.suffix == RRI { this.EncodeRri(word_) } else if this.suffix == RRIC { this.EncodeRric(word_) } else if this.suffix == RRICI { this.EncodeRrici(word_) } else if this.suffix == RRIF { this.EncodeRrif(word_) } else if this.suffix == RRR { this.EncodeRrr(word_) } else if this.suffix == RRRC { this.EncodeRrrc(word_) } else if this.suffix == RRRCI { this.EncodeRrrci(word_) } else if this.suffix == ZRI { this.EncodeZri(word_) } else if this.suffix == ZRIC { this.EncodeZric(word_) } else if this.suffix == ZRICI { this.EncodeZrici(word_) } else if this.suffix == ZRIF { this.EncodeZrif(word_) } else if this.suffix == ZRR { this.EncodeZrr(word_) } else if this.suffix == ZRRC { this.EncodeZrrc(word_) } else if this.suffix == ZRRCI { this.EncodeZrrci(word_) } else if this.suffix == S_RRI || this.suffix == U_RRI { this.EncodeSRri(word_) } else if this.suffix == S_RRIC || this.suffix == U_RRIC { this.EncodeSRric(word_) } else if this.suffix == S_RRICI || this.suffix == U_RRICI { this.EncodeSRrici(word_) } else if this.suffix == S_RRIF || this.suffix == U_RRIF { this.EncodeSRrif(word_) } else if this.suffix == S_RRR || this.suffix == U_RRR { this.EncodeSRrr(word_) } else if this.suffix == S_RRRC || this.suffix == U_RRRC { this.EncodeSRrrc(word_) } else if this.suffix == S_RRRCI || this.suffix == U_RRRCI { this.EncodeSRrrci(word_) } else if this.suffix == RR { this.EncodeRr(word_) } else if this.suffix == RRC { this.EncodeRrc(word_) } else if this.suffix == RRCI { this.EncodeRrci(word_) } else if this.suffix == ZR { this.EncodeZr(word_) } else if this.suffix == ZRC { this.EncodeZrc(word_) } else if this.suffix == ZRCI { this.EncodeZrci(word_) } else if this.suffix == S_RR || this.suffix == U_RR { this.EncodeSRr(word_) } else if this.suffix == S_RRC || this.suffix == U_RRC { this.EncodeSRrc(word_) } else if this.suffix == S_RRCI || this.suffix == U_RRCI { this.EncodeSRrci(word_) } else if this.suffix == DRDICI { this.EncodeDrdici(word_) } else if this.suffix == RRRI { this.EncodeRrri(word_) } else if this.suffix == RRRICI { this.EncodeRrrici(word_) } else if this.suffix == ZRRI { this.EncodeZrri(word_) } else if this.suffix == ZRRICI { this.EncodeZrrici(word_) } else if this.suffix == S_RRRI || this.suffix == U_RRRI { this.EncodeSRrri(word_) } else if this.suffix == S_RRRICI || this.suffix == U_RRRICI { this.EncodeSRrrici(word_) } else if this.suffix == RIR { this.EncodeRir(word_) } else if this.suffix == RIRC { this.EncodeRirc(word_) } else if this.suffix == RIRCI { this.EncodeRirci(word_) } else if this.suffix == ZIR { this.EncodeZir(word_) } else if this.suffix == ZIRC { this.EncodeZirc(word_) } else if this.suffix == ZIRCI { this.EncodeZirci(word_) } else if this.suffix == S_RIRC || this.suffix == U_RIRC { this.EncodeSRirc(word_) } else if this.suffix == S_RIRCI || this.suffix == U_RIRCI { this.EncodeSRirci(word_) } else if this.suffix == R { this.EncodeR(word_) } else if this.suffix == RCI { this.EncodeRci(word_) } else if this.suffix == Z { this.EncodeZ(word_) } else if this.suffix == ZCI { this.EncodeZci(word_) } else if this.suffix == S_R || this.suffix == U_R { this.EncodeSR(word_) } else if this.suffix == S_RCI || this.suffix == U_RCI { this.EncodeSRci(word_) } else if this.suffix == CI { this.EncodeCi(word_) } else if this.suffix == I { this.EncodeI(word_) } else if this.suffix == DDCI { this.EncodeDdci(word_) } else if this.suffix == ERRI { this.EncodeErri(word_) } else if this.suffix == S_ERRI || this.suffix == U_ERRI { this.EncodeSErri(word_) } else if this.suffix == EDRI { this.EncodeEdri(word_) } else if this.suffix == ERII { this.EncodeErii(word_) } else if this.suffix == ERIR { this.EncodeErir(word_) } else if this.suffix == ERID { this.EncodeErid(word_) } else if this.suffix == DMA_RRI { this.EncodeDmaRri(word_) } else { err := errors.New("op code is not valid") panic(err) } return word_.ToByteStream() } func (this *Instruction) EncodeRici(word_ *abi.Word) { if _, found := this.RiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } if this.suffix != RICI { err := errors.New("suffix is not RICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.pc.Width() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != RRI { err := errors.New("suffix is not RRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeRric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != RRIC { err := errors.New("suffix is not RRIC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != RRICI { err := errors.New("suffix is not RRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != RRIF { err := errors.New("suffix is not RRIF") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not RRR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeRrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != RRRC { err := errors.New("suffix is not RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != ZRI { err := errors.New("suffix is not ZRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeZric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != ZRIF { err := errors.New("suffix is not RRIF") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != ZRR { err := errors.New("suffix is not RRR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeZrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != S_RRI && this.suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeSRric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != S_RRIC && this.suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != S_RRICI && this.suffix != U_RRICI { err := errors.New("suffix is not RRICI nor U_RRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != S_RRIF && this.suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) imm_begin := ra_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeSRrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != S_RRRC && this.suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != S_RRRCI && this.suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != RR { err := errors.New("suffix is not RR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeRrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != RRC { err := errors.New("suffix is not RRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != RRCI { err := errors.New("suffix is not RRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != ZR { err := errors.New("suffix is not ZR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeZrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != ZRC { err := errors.New("suffix is not RRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != S_RR && this.suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeSRrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != S_RRC && this.suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != S_RRCI && this.suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeDrdici(word_ *abi.Word) { if _, found := this.DrdiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } if this.suffix != DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) db_begin := ra_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) imm_begin := db_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != RRRI { err := errors.New("suffix is not RRRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeRrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeZrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != S_RRRI && this.suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeSRrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != S_RRRICI && this.suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeRir(word_ *abi.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != RIR { err := errors.New("suffix is not RIR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeRirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != RIRC { err := errors.New("suffix is not RIRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeRirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) imm_begin := rc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZir(word_ *abi.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != ZIR { err := errors.New("suffix is not ZIR") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) } func (this *Instruction) EncodeZirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeZirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSRirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != S_RIRC && this.suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) imm_begin := dc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) } func (this *Instruction) EncodeSRirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != S_RIRCI && this.suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) imm_begin := dc_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeR(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != R { err := errors.New("suffix is not R") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) } func (this *Instruction) EncodeRci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != RCI { err := errors.New("suffix is not RCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) condition_begin := rc_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeZ(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found && this.op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } if this.suffix != Z { err := errors.New("suffix is not Z") panic(err) } } func (this *Instruction) EncodeZci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != ZCI { err := errors.New("suffix is not ZCI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeSR(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != S_R && this.suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) } func (this *Instruction) EncodeSRci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != S_RCI && this.suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) condition_begin := dc_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeCi(word_ *abi.Word) { if _, found := this.CiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } if this.suffix != CI { err := errors.New("suffix is not CI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeI(word_ *abi.Word) { if _, found := this.IOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } if this.suffix != I { err := errors.New("suffix is not I") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeDdci(word_ *abi.Word) { if _, found := this.DdciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } if this.suffix != DDCI { err := errors.New("suffix is not DDCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) db_begin := dc_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) condition_begin := db_end condition_end := condition_begin + this.ConditionWidth() this.EncodeCondition(word_, condition_begin, condition_end, *this.condition) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() this.EncodePc(word_, pc_begin, pc_end, this.pc.Value()) } func (this *Instruction) EncodeErri(word_ *abi.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != ERRI { err := errors.New("suffix is not ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) rc_begin := endian_end rc_end := rc_begin + this.RegisterWidth() this.EncodeGpRegDescriptor(word_, rc_begin, rc_end, this.rc) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeSErri(word_ *abi.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != S_ERRI && this.suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeEdri(word_ *abi.Word) { if _, found := this.EdriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } if this.suffix != EDRI { err := errors.New("suffix is not EDRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, dc_begin, dc_end, this.dc) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) } func (this *Instruction) EncodeErii(word_ *abi.Word) { if _, found := this.EriiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } if this.suffix != ERII { err := errors.New("suffix is not ERII") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) imm_begin := off_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeErir(word_ *abi.Word) { if _, found := this.ErirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } if this.suffix != ERIR { err := errors.New("suffix is not ERIR") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) rb_begin := off_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) } func (this *Instruction) EncodeErid(word_ *abi.Word) { if _, found := this.EridOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } if this.suffix != ERID { err := errors.New("suffix is not ERID") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.EncodeEndian(word_, endian_begin, endian_end, *this.endian) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) off_begin := ra_end off_end := off_begin + this.off.Width() this.EncodeOff(word_, off_begin, off_end, this.off.Value()) db_begin := off_end db_end := db_begin + this.RegisterWidth() this.EncodePairRegDescriptor(word_, db_begin, db_end, this.db) } func (this *Instruction) EncodeDmaRri(word_ *abi.Word) { if _, found := this.DmaRriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } if this.suffix != DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, ra_begin, ra_end, this.ra) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.EncodeSrcRegDescriptor(word_, rb_begin, rb_end, this.rb) imm_begin := rb_end imm_end := imm_begin + this.imm.Width() this.EncodeImm(word_, imm_begin, imm_end, this.imm.Value()) } func (this *Instruction) EncodeOpCode(word_ *abi.Word) { word_.SetBitSlice(this.OpCodeBegin(), this.OpCodeEnd(), int64(this.op_code)) } func (this *Instruction) EncodeSuffix(word_ *abi.Word) { word_.SetBitSlice(this.SuffixBegin(), this.SuffixEnd(), int64(this.suffix)) } func (this *Instruction) EncodeGpRegDescriptor( word_ *abi.Word, begin int, end int, gp_reg_descriptor *reg_descriptor.GpRegDescriptor, ) { word_.SetBitSlice(begin, end, int64(gp_reg_descriptor.Index())) } func (this *Instruction) EncodeSrcRegDescriptor( word_ *abi.Word, begin int, end int, src_reg_descriptor *reg_descriptor.SrcRegDescriptor, ) { if src_reg_descriptor.IsGpRegDescriptor() { word_.SetBitSlice(begin, end, int64(src_reg_descriptor.GpRegDescriptor().Index())) } else if src_reg_descriptor.IsSpRegDescriptor() { config_loader := new(misc.ConfigLoader) config_loader.Init() index := config_loader.NumGpRegisters() + int(*src_reg_descriptor.SpRegDescriptor()) word_.SetBitSlice(begin, end, int64(index)) } else { err := errors.New("sp reg descriptor is corrupted") panic(err) } } func (this *Instruction) EncodePairRegDescriptor( word_ *abi.Word, begin int, end int, pair_reg_descriptor *reg_descriptor.PairRegDescriptor, ) { word_.SetBitSlice(begin, end, int64(pair_reg_descriptor.Index())) } func (this *Instruction) EncodeImm(word_ *abi.Word, begin int, end int, value int64) { word_.SetBitSlice(begin, end, value) } func (this *Instruction) EncodeCondition( word_ *abi.Word, begin int, end int, condition cc.Condition, ) { word_.SetBitSlice(begin, end, int64(condition)) } func (this *Instruction) EncodePc(word_ *abi.Word, begin int, end int, pc int64) { this.EncodeImm(word_, begin, end, pc) } func (this *Instruction) EncodeEndian(word_ *abi.Word, begin int, end int, endian Endian) { word_.SetBitSlice(begin, end, int64(endian)) } func (this *Instruction) EncodeOff(word_ *abi.Word, begin int, end int, value int64) { this.EncodeImm(word_, begin, end, value) } func (this *Instruction) Decode(byte_stream *encoding.ByteStream) { config_loader := new(misc.ConfigLoader) config_loader.Init() word_ := new(abi.Word) word_.Init(config_loader.IramDataWidth()) word_.FromByteStream(byte_stream) this.op_code = this.DecodeOpCode(word_) this.suffix = this.DecodeSuffix(word_) if this.suffix == RICI { this.DecodeRici(word_) } else if this.suffix == RRI { this.DecodeRri(word_) } else if this.suffix == RRIC { this.DecodeRric(word_) } else if this.suffix == RRICI { this.DecodeRrici(word_) } else if this.suffix == RRIF { this.DecodeRrif(word_) } else if this.suffix == RRR { this.DecodeRrr(word_) } else if this.suffix == RRRC { this.DecodeRrrc(word_) } else if this.suffix == RRRCI { this.DecodeRrrci(word_) } else if this.suffix == ZRI { this.DecodeZri(word_) } else if this.suffix == ZRIC { this.DecodeZric(word_) } else if this.suffix == ZRICI { this.DecodeZrici(word_) } else if this.suffix == ZRIF { this.DecodeZrif(word_) } else if this.suffix == ZRR { this.DecodeZrr(word_) } else if this.suffix == ZRRC { this.DecodeZrrc(word_) } else if this.suffix == ZRRCI { this.DecodeZrrci(word_) } else if this.suffix == S_RRI || this.suffix == U_RRI { this.DecodeSRri(word_) } else if this.suffix == S_RRIC || this.suffix == U_RRIC { this.DecodeSRric(word_) } else if this.suffix == S_RRICI || this.suffix == U_RRICI { this.DecodeSRrici(word_) } else if this.suffix == S_RRIF || this.suffix == U_RRIF { this.DecodeSRrif(word_) } else if this.suffix == S_RRR || this.suffix == U_RRR { this.DecodeSRrr(word_) } else if this.suffix == S_RRRC || this.suffix == U_RRRC { this.DecodeSRrrc(word_) } else if this.suffix == S_RRRCI || this.suffix == U_RRRCI { this.DecodeSRrrci(word_) } else if this.suffix == RR { this.DecodeRr(word_) } else if this.suffix == RRC { this.DecodeRrc(word_) } else if this.suffix == RRCI { this.DecodeRrci(word_) } else if this.suffix == ZR { this.DecodeZr(word_) } else if this.suffix == ZRC { this.DecodeZrc(word_) } else if this.suffix == ZRCI { this.DecodeZrci(word_) } else if this.suffix == S_RR || this.suffix == U_RR { this.DecodeSRr(word_) } else if this.suffix == S_RRC || this.suffix == U_RRC { this.DecodeSRrc(word_) } else if this.suffix == S_RRCI || this.suffix == U_RRCI { this.DecodeSRrci(word_) } else if this.suffix == DRDICI { this.DecodeDrdici(word_) } else if this.suffix == RRRI { this.DecodeRrri(word_) } else if this.suffix == RRRICI { this.DecodeRrrici(word_) } else if this.suffix == ZRRI { this.DecodeZrri(word_) } else if this.suffix == ZRRICI { this.DecodeZrrici(word_) } else if this.suffix == S_RRRI || this.suffix == U_RRRI { this.DecodeSRrri(word_) } else if this.suffix == S_RRRICI || this.suffix == U_RRRICI { this.DecodeSRrrici(word_) } else if this.suffix == RIR { this.DecodeRir(word_) } else if this.suffix == RIRC { this.DecodeRirc(word_) } else if this.suffix == RIRCI { this.DecodeRirci(word_) } else if this.suffix == ZIR { this.DecodeZir(word_) } else if this.suffix == ZIRC { this.DecodeZirc(word_) } else if this.suffix == ZIRCI { this.DecodeZirci(word_) } else if this.suffix == S_RIRC || this.suffix == U_RIRC { this.DecodeSRirc(word_) } else if this.suffix == S_RIRCI || this.suffix == U_RIRCI { this.DecodeSRirci(word_) } else if this.suffix == R { this.DecodeR(word_) } else if this.suffix == RCI { this.DecodeRci(word_) } else if this.suffix == Z { this.DecodeZ(word_) } else if this.suffix == ZCI { this.DecodeZci(word_) } else if this.suffix == S_R || this.suffix == U_R { this.DecodeSR(word_) } else if this.suffix == S_RCI || this.suffix == U_RCI { this.DecodeSRci(word_) } else if this.suffix == CI { this.DecodeCi(word_) } else if this.suffix == I { this.DecodeI(word_) } else if this.suffix == DDCI { this.DecodeDdci(word_) } else if this.suffix == ERRI { this.DecodeErri(word_) } else if this.suffix == S_ERRI || this.suffix == U_ERRI { this.DecodeSErri(word_) } else if this.suffix == EDRI { this.DecodeEdri(word_) } else if this.suffix == ERII { this.DecodeErii(word_) } else if this.suffix == ERIR { this.DecodeErir(word_) } else if this.suffix == ERID { this.DecodeErid(word_) } else if this.suffix == DMA_RRI { this.DecodeDmaRri(word_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Instruction) DecodeRici(word_ *abi.Word) { if _, found := this.RiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } if this.suffix != RICI { err := errors.New("suffix is not RICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 16 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 16, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() condition := this.DecodeCondition(word_, condition_begin, condition_end) this.condition = new(cc.Condition) *this.condition = condition pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.SIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != RRI { err := errors.New("suffix is not RRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeRric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != RRIC { err := errors.New("suffix is not RRIC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != RRICI { err := errors.New("suffix is not RRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != RRIF { err := errors.New("suffix is not RRIF") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != RRR { err := errors.New("suffix is not RRR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeRrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != RRRC { err := errors.New("suffix is not RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != ZRI { err := errors.New("suffix is not ZRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 28 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 28, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeZric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != ZRIC { err := errors.New("suffix is not RRIC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 11 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 11, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != ZRIF { err := errors.New("suffix is not ZRIF") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 27 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 27, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != ZRR { err := errors.New("suffix is not ZRR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeZrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRri(word_ *abi.Word) { if _, found := this.RriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } if this.suffix != S_RRI && this.suffix != U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end if _, is_add_rri_op_code := this.AddRriOpCodes()[this.op_code]; is_add_rri_op_code { imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) } else if _, is_asr_rri_op_code := this.AsrRriOpCodes()[this.op_code]; is_asr_rri_op_code { imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_call_rri_op_code := this.CallRriOpCodes()[this.op_code]; is_call_rri_op_code { imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRI op code") panic(err) } } func (this *Instruction) DecodeSRric(word_ *abi.Word) { if _, found := this.RricOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } if this.suffix != S_RRIC && this.suffix != U_RRIC { err := errors.New("suffix is not S_RRIC nor U_RRIC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rric_op_code := this.AddRricOpCodes()[this.op_code]; is_add_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else if _, is_asr_rric_op_code := this.AsrRricOpCodes()[this.op_code]; is_asr_rric_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_sub_rric_op_code := this.SubRricOpCodes()[this.op_code]; is_sub_rric_op_code { imm_end = imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } else { err := errors.New("op code is not a valid RRIC op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrici(word_ *abi.Word) { if _, found := this.RriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } if this.suffix != S_RRICI && this.suffix != U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end var imm_end int if _, is_add_rrici_op_code := this.AddRriciOpCodes()[this.op_code]; is_add_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else if _, is_asr_rrici_op_code := this.AsrRriciOpCodes()[this.op_code]; is_asr_rrici_op_code { imm_end = imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } else if _, is_and_rrici_op_code := this.AndRriciOpCodes()[this.op_code]; is_and_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else if _, is_sub_rrici_op_code := this.SubRriciOpCodes()[this.op_code]; is_sub_rrici_op_code { imm_end = imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) } else { err := errors.New("op code is not a valid RRICI op code") panic(err) } condition_begin := imm_end condition_end := imm_end + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRrif(word_ *abi.Word) { if _, found := this.RrifOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } if this.suffix != S_RRIF && this.suffix != U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) imm_begin := ra_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrr(word_ *abi.Word) { if _, found := this.RrrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } if this.suffix != S_RRR { err := errors.New("suffix is not S_RRR nor U_RRR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeSRrrc(word_ *abi.Word) { if _, found := this.RrrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } if this.suffix != S_RRRC && this.suffix != U_RRRC { err := errors.New("suffix is not S_RRRC nor U_RRRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrrci(word_ *abi.Word) { if _, found := this.RrrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } if this.suffix != S_RRRCI && this.suffix != U_RRRCI { err := errors.New("suffix is not S_RRRCI nor U_RRRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) condition_begin := rb_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != RR { err := errors.New("suffix is not RR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeRrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != RRC { err := errors.New("suffix is not RRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != RRCI { err := errors.New("suffix is not RRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != ZR { err := errors.New("suffix is not ZR") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeZrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != ZRC { err := errors.New("suffix is not ZRC") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRr(word_ *abi.Word) { if _, found := this.RrOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } if this.suffix != S_RR && this.suffix != U_RR { err := errors.New("suffix is not S_RR nor U_RR") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeSRrc(word_ *abi.Word) { if _, found := this.RrcOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } if this.suffix != S_RRC && this.suffix != U_RRC { err := errors.New("suffix is not S_RRC nor U_RRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRrci(word_ *abi.Word) { if _, found := this.RrciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } if this.suffix != S_RRCI && this.suffix != U_RRCI { err := errors.New("suffix is not S_RRCI nor U_RRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodePc(word_, pc_begin, pc_end) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeDrdici(word_ *abi.Word) { if _, found := this.DrdiciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } if this.suffix != DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) db_begin := ra_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) imm_begin := db_end imm_end := imm_begin + 5 imm := this.DecodePc(word_, imm_begin, imm_end) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != RRRI { err := errors.New("suffix is not RRRI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) DecodeRrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) DecodeZrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRrri(word_ *abi.Word) { if _, found := this.RrriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } if this.suffix != S_RRRI && this.suffix != U_RRRI { err := errors.New("suffix is not S_RRRI nor U_RRRI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) } func (this *Instruction) DecodeSRrrici(word_ *abi.Word) { if _, found := this.RrriciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } if this.suffix != S_RRRICI && this.suffix != U_RRRICI { err := errors.New("suffix is not S_RRRICI nor U_RRRICI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 5 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 5, imm) condition_begin := imm_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeRir(word_ *abi.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != RIR { err := errors.New("suffix is not RIR") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeRirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != RIRC { err := errors.New("suffix is not RIRC") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeRirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) imm_begin := rc_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZir(word_ *abi.Word) { if _, found := this.RirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } if this.suffix != ZIR { err := errors.New("suffix is not ZIR") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 32 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 32, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) } func (this *Instruction) DecodeZirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeZirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSRirc(word_ *abi.Word) { if _, found := this.RircOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } if this.suffix != S_RIRC && this.suffix != U_RIRC { err := errors.New("suffix is not S_RIRC nor U_RIRC") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) imm_begin := dc_end imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) } func (this *Instruction) DecodeSRirci(word_ *abi.Word) { if _, found := this.RirciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } if this.suffix != S_RIRCI && this.suffix != U_RIRCI { err := errors.New("suffix is not S_RIRCI nor U_RIRCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) imm_begin := dc_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 8, imm) ra_begin := imm_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) condition_begin := ra_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeR(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != R { err := errors.New("suffix is not R") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) } func (this *Instruction) DecodeRci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != RCI { err := errors.New("suffix is not RCI") panic(err) } rc_begin := this.SuffixEnd() rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) condition_begin := rc_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeZ(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found && this.op_code != NOP { err := errors.New("op code is not a valid R op code nor NOP") panic(err) } if this.suffix != Z { err := errors.New("suffix is not R") panic(err) } } func (this *Instruction) DecodeZci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != ZCI { err := errors.New("suffix is not ZCI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeSR(word_ *abi.Word) { if _, found := this.ROpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid R op code") panic(err) } if this.suffix != S_R && this.suffix != U_R { err := errors.New("suffix is not S_R nor U_R") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) } func (this *Instruction) DecodeSRci(word_ *abi.Word) { if _, found := this.RciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid RCI op code") panic(err) } if this.suffix != S_RCI && this.suffix != U_RCI { err := errors.New("suffix is not S_RCI nor U_RCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) condition_begin := dc_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeCi(word_ *abi.Word) { if _, found := this.CiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } if this.suffix != CI { err := errors.New("suffix is not CI") panic(err) } condition_begin := this.SuffixEnd() condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeI(word_ *abi.Word) { if _, found := this.IOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid I op code") panic(err) } if this.suffix != I { err := errors.New("suffix is not I") panic(err) } imm_begin := this.SuffixEnd() imm_end := imm_begin + 24 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 24, imm) } func (this *Instruction) DecodeDdci(word_ *abi.Word) { if _, found := this.DdciOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } if this.suffix != DDCI { err := errors.New("suffix is not DDCI") panic(err) } dc_begin := this.SuffixEnd() dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) db_begin := dc_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) condition_begin := db_end condition_end := condition_begin + this.ConditionWidth() this.condition = new(cc.Condition) *this.condition = this.DecodeCondition(word_, condition_begin, condition_end) pc_begin := condition_end pc_end := pc_begin + this.PcWidth() pc := this.DecodeImm(word_, pc_begin, pc_end, abi.UNSIGNED) this.pc = new(abi.Immediate) this.pc.Init(abi.UNSIGNED, this.PcWidth(), pc) } func (this *Instruction) DecodeErri(word_ *abi.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != ERRI { err := errors.New("suffix is not ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) rc_begin := endian_end rc_end := rc_begin + this.RegisterWidth() this.rc = this.DecodeGpRegDescriptor(word_, rc_begin, rc_end) ra_begin := rc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) DecodeSErri(word_ *abi.Word) { if _, found := this.ErriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } if this.suffix != S_ERRI && this.suffix != U_ERRI { err := errors.New("suffix is not S_ERRI nor U_ERRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) DecodeEdri(word_ *abi.Word) { if _, found := this.EdriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } if this.suffix != EDRI { err := errors.New("suffix is not EDRI") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) dc_begin := endian_end dc_end := dc_begin + this.RegisterWidth() this.dc = this.DecodePairRegDescriptor(word_, dc_begin, dc_end) ra_begin := dc_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) } func (this *Instruction) DecodeErii(word_ *abi.Word) { if _, found := this.EriiOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } if this.suffix != ERII { err := errors.New("suffix is not ERII") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) imm_begin := off_end imm_end := imm_begin + 16 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.SIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.SIGNED, 16, imm) } func (this *Instruction) DecodeErir(word_ *abi.Word) { if _, found := this.ErirOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } if this.suffix != ERIR { err := errors.New("suffix is not ERIR") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) rb_begin := off_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) } func (this *Instruction) DecodeErid(word_ *abi.Word) { if _, found := this.EridOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } if this.suffix != ERID { err := errors.New("suffix is not ERID") panic(err) } endian_begin := this.SuffixEnd() endian_end := endian_begin + this.EndianWidth() this.endian = new(Endian) *this.endian = this.DecodeEndian(word_, endian_begin, endian_end) ra_begin := endian_end ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) off_begin := ra_end off_end := off_begin + 24 off := this.DecodeOff(word_, off_begin, off_end, abi.SIGNED) this.off = new(abi.Immediate) this.off.Init(abi.SIGNED, 24, off) db_begin := off_end db_end := db_begin + this.RegisterWidth() this.db = this.DecodePairRegDescriptor(word_, db_begin, db_end) } func (this *Instruction) DecodeDmaRri(word_ *abi.Word) { if _, found := this.DmaRriOpCodes()[this.op_code]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } if this.suffix != DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } ra_begin := this.SuffixEnd() ra_end := ra_begin + this.RegisterWidth() this.ra = this.DecodeSrcRegDescriptor(word_, ra_begin, ra_end) rb_begin := ra_end rb_end := rb_begin + this.RegisterWidth() this.rb = this.DecodeSrcRegDescriptor(word_, rb_begin, rb_end) imm_begin := rb_end imm_end := imm_begin + 8 imm := this.DecodeImm(word_, imm_begin, imm_end, abi.UNSIGNED) this.imm = new(abi.Immediate) this.imm.Init(abi.UNSIGNED, 8, imm) } func (this *Instruction) DecodeOpCode(word_ *abi.Word) OpCode { return OpCode(word_.BitSlice(abi.UNSIGNED, this.OpCodeBegin(), this.OpCodeEnd())) } func (this *Instruction) DecodeSuffix(word_ *abi.Word) Suffix { return Suffix(word_.BitSlice(abi.UNSIGNED, this.SuffixBegin(), this.SuffixEnd())) } func (this *Instruction) DecodeGpRegDescriptor( word_ *abi.Word, begin int, end int, ) *reg_descriptor.GpRegDescriptor { index := int(word_.BitSlice(abi.UNSIGNED, begin, end)) gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) return gp_reg_descriptor } func (this *Instruction) DecodeSrcRegDescriptor( word_ *abi.Word, begin int, end int, ) *reg_descriptor.SrcRegDescriptor { index := int(word_.BitSlice(abi.UNSIGNED, begin, end)) config_loader := new(misc.ConfigLoader) config_loader.Init() if index < config_loader.NumGpRegisters() { gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitGpRegDescriptor(gp_reg_descriptor) return src_reg_descriptor } else { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.SpRegDescriptor(index - config_loader.NumGpRegisters()) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } } func (this *Instruction) DecodePairRegDescriptor( word_ *abi.Word, begin int, end int, ) *reg_descriptor.PairRegDescriptor { index := int(word_.BitSlice(abi.UNSIGNED, begin, end)) pair_reg_descriptor := new(reg_descriptor.PairRegDescriptor) pair_reg_descriptor.Init(index) return pair_reg_descriptor } func (this *Instruction) DecodeImm( word_ *abi.Word, begin int, end int, representation abi.Representation, ) int64 { return word_.BitSlice(representation, begin, end) } func (this *Instruction) DecodeCondition(word_ *abi.Word, begin int, end int) cc.Condition { return cc.Condition(word_.BitSlice(abi.UNSIGNED, begin, end)) } func (this *Instruction) DecodePc(word_ *abi.Word, begin int, end int) int64 { return this.DecodeImm(word_, begin, end, abi.UNSIGNED) } func (this *Instruction) DecodeEndian(word_ *abi.Word, begin int, end int) Endian { return Endian(word_.BitSlice(abi.UNSIGNED, begin, end)) } func (this *Instruction) DecodeOff( word_ *abi.Word, begin int, end int, representation abi.Representation, ) int64 { return this.DecodeImm(word_, begin, end, representation) } func (this *Instruction) OpCodeBegin() int { return 0 } func (this *Instruction) OpCodeEnd() int { return this.OpCodeBegin() + this.OpCodeWidth() } func (this *Instruction) OpCodeWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(SDMA)))) } func (this *Instruction) SuffixBegin() int { return this.OpCodeEnd() } func (this *Instruction) SuffixEnd() int { return this.SuffixBegin() + this.SuffixWidth() } func (this *Instruction) SuffixWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(DMA_RRI)))) } func (this *Instruction) RegisterWidth() int { config_loader := new(misc.ConfigLoader) config_loader.Init() return int( math.Ceil( math.Log2(float64(config_loader.NumGpRegisters()) + 1.0 + float64(reg_descriptor.ID8)), ), ) } func (this *Instruction) ConditionWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(cc.LARGE)))) } func (this *Instruction) PcWidth() int { config_loader := new(misc.ConfigLoader) config_loader.Init() return config_loader.AddressWidth() } func (this *Instruction) EndianWidth() int { return int(math.Ceil(math.Log2(1.0 + float64(BIG)))) } func (this *Instruction) AcquireRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ACQUIRE: true, } } func (this *Instruction) ReleaseRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ RELEASE: true, } } func (this *Instruction) BootRiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ BOOT: true, RESUME: true, } } func (this *Instruction) RiciOpCodes() map[OpCode]bool { acquire_rici_op_codes := this.AcquireRiciOpCodes() release_rici_op_codes := this.ReleaseRiciOpCodes() boot_rici_op_codes := this.BootRiciOpCodes() rici_op_codes := make(map[OpCode]bool) for k, v := range acquire_rici_op_codes { rici_op_codes[k] = v } for k, v := range release_rici_op_codes { rici_op_codes[k] = v } for k, v := range boot_rici_op_codes { rici_op_codes[k] = v } return rici_op_codes } func (this *Instruction) AddRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, OR: true, XOR: true, } } func (this *Instruction) AsrRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) CallRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ CALL: true, } } func (this *Instruction) RriOpCodes() map[OpCode]bool { add_rri_op_codes := this.AddRriOpCodes() asr_rri_op_codes := this.AsrRriOpCodes() call_rri_op_codes := this.CallRriOpCodes() rri_op_codes := make(map[OpCode]bool) for k, v := range add_rri_op_codes { rri_op_codes[k] = v } for k, v := range asr_rri_op_codes { rri_op_codes[k] = v } for k, v := range call_rri_op_codes { rri_op_codes[k] = v } return rri_op_codes } func (this *Instruction) AddRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) SubRricOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RricOpCodes() map[OpCode]bool { add_rric_op_codes := this.AddRricOpCodes() asr_rric_op_codes := this.AsrRricOpCodes() sub_rric_op_codes := this.SubRricOpCodes() rric_op_codes := make(map[OpCode]bool) for k, v := range add_rric_op_codes { rric_op_codes[k] = v } for k, v := range asr_rric_op_codes { rric_op_codes[k] = v } for k, v := range sub_rric_op_codes { rric_op_codes[k] = v } return rric_op_codes } func (this *Instruction) AddRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, } } func (this *Instruction) AndRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) SubRriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RriciOpCodes() map[OpCode]bool { add_rrici_op_codes := this.AddRriciOpCodes() and_rrici_op_codes := this.AndRriciOpCodes() asr_rrici_op_codes := this.AsrRriciOpCodes() sub_rrici_op_codes := this.SubRriciOpCodes() rrici_op_codes := make(map[OpCode]bool) for k, v := range add_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range and_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range asr_rrici_op_codes { rrici_op_codes[k] = v } for k, v := range sub_rrici_op_codes { rrici_op_codes[k] = v } return rrici_op_codes } func (this *Instruction) RrifOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, SUB: true, SUBC: true, XOR: true, HASH: true, } } func (this *Instruction) RrrOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, ROL: true, ROR: true, RSUB: true, RSUBC: true, SUB: true, SUBC: true, XOR: true, HASH: true, CALL: true, } } func (this *Instruction) AddRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, AND: true, ANDN: true, ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, NAND: true, NOR: true, NXOR: true, ROL: true, ROR: true, OR: true, ORN: true, XOR: true, HASH: true, CALL: true, } } func (this *Instruction) RsubRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ RSUB: true, RSUBC: true, } } func (this *Instruction) SubRrrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RrrcOpCodes() map[OpCode]bool { add_rrrc_op_codes := this.AddRrrcOpCodes() rsub_rrrc_op_codes := this.RsubRrrcOpCodes() sub_rrrc_op_codes := this.SubRrrcOpCodes() rrrc_op_codes := make(map[OpCode]bool) for k, v := range add_rrrc_op_codes { rrrc_op_codes[k] = v } for k, v := range rsub_rrrc_op_codes { rrrc_op_codes[k] = v } for k, v := range sub_rrrc_op_codes { rrrc_op_codes[k] = v } return rrrc_op_codes } func (this *Instruction) AddRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ADD: true, ADDC: true, } } func (this *Instruction) AndRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ AND: true, ANDN: true, NAND: true, NOR: true, NXOR: true, OR: true, ORN: true, XOR: true, HASH: true, } } func (this *Instruction) AsrRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ ASR: true, CMPB4: true, LSL: true, LSL1: true, LSL1X: true, LSLX: true, LSR: true, LSR1: true, LSR1X: true, LSRX: true, ROL: true, ROR: true, } } func (this *Instruction) MulRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MUL_SH_SH: true, MUL_SH_SL: true, MUL_SH_UH: true, MUL_SH_UL: true, MUL_SL_SH: true, MUL_SL_SL: true, MUL_SL_UH: true, MUL_SL_UL: true, MUL_UH_UH: true, MUL_UH_UL: true, MUL_UL_UH: true, MUL_UL_UL: true, } } func (this *Instruction) RsubRrrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ RSUB: true, RSUBC: true, SUB: true, SUBC: true, } } func (this *Instruction) RrrciOpCodes() map[OpCode]bool { add_rrrci_op_codes := this.AddRrrciOpCodes() and_rrrci_op_codes := this.AndRrrciOpCodes() asr_rrrci_op_codes := this.AsrRrrciOpCodes() mul_rrrci_op_codes := this.MulRrrciOpCodes() rsub_rrrci_op_codes := this.RsubRrrciOpCodes() rrrci_op_codes := make(map[OpCode]bool) for k, v := range add_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range and_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range asr_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range mul_rrrci_op_codes { rrrci_op_codes[k] = v } for k, v := range rsub_rrrci_op_codes { rrrci_op_codes[k] = v } return rrrci_op_codes } func (this *Instruction) RrOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, TIME_CFG: true, } } func (this *Instruction) RrcOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, } } func (this *Instruction) CaoRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ CAO: true, CLO: true, CLS: true, CLZ: true, } } func (this *Instruction) ExtsbRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ EXTSB: true, EXTSH: true, EXTUB: true, EXTUH: true, SATS: true, } } func (this *Instruction) TimeCfgRrciOpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME_CFG: true, } } func (this *Instruction) RrciOpCodes() map[OpCode]bool { cao_rrci_op_codes := this.CaoRrciOpCodes() extsb_rrci_op_codes := this.ExtsbRrciOpCodes() time_cfg_rrci_op_codes := this.TimeCfgRrciOpCodes() rrci_op_codes := make(map[OpCode]bool) for k, v := range cao_rrci_op_codes { rrci_op_codes[k] = v } for k, v := range extsb_rrci_op_codes { rrci_op_codes[k] = v } for k, v := range time_cfg_rrci_op_codes { rrci_op_codes[k] = v } return rrci_op_codes } func (this *Instruction) DivStepDrdiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ DIV_STEP: true, } } func (this *Instruction) MulStepDrdiciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MUL_STEP: true, } } func (this *Instruction) DrdiciOpCodes() map[OpCode]bool { div_step_drdici_op_codes := this.DivStepDrdiciOpCodes() mul_step_drdici_op_codes := this.MulStepDrdiciOpCodes() drdici_op_codes := make(map[OpCode]bool) for k, v := range div_step_drdici_op_codes { drdici_op_codes[k] = v } for k, v := range mul_step_drdici_op_codes { drdici_op_codes[k] = v } return drdici_op_codes } func (this *Instruction) RrriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LSL_ADD: true, LSL_SUB: true, LSR_ADD: true, ROL_ADD: true, } } func (this *Instruction) RrriciOpCodes() map[OpCode]bool { return map[OpCode]bool{ LSL_ADD: true, LSL_SUB: true, LSR_ADD: true, ROL_ADD: true, } } func (this *Instruction) RirOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RircOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) RirciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SUB: true, SUBC: true, } } func (this *Instruction) ROpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME: true, } } func (this *Instruction) RciOpCodes() map[OpCode]bool { return map[OpCode]bool{ TIME: true, } } func (this *Instruction) CiOpCodes() map[OpCode]bool { return map[OpCode]bool{ STOP: true, } } func (this *Instruction) IOpCodes() map[OpCode]bool { return map[OpCode]bool{ FAULT: true, } } func (this *Instruction) MovdDdciOpCodes() map[OpCode]bool { return map[OpCode]bool{ MOVD: true, } } func (this *Instruction) SwapdDdciOpCodes() map[OpCode]bool { return map[OpCode]bool{ SWAPD: true, } } func (this *Instruction) DdciOpCodes() map[OpCode]bool { movd_ddci_op_codes := this.MovdDdciOpCodes() swapd_ddci_op_codes := this.SwapdDdciOpCodes() ddci_op_codes := make(map[OpCode]bool) for k, v := range movd_ddci_op_codes { ddci_op_codes[k] = v } for k, v := range swapd_ddci_op_codes { ddci_op_codes[k] = v } return ddci_op_codes } func (this *Instruction) ErriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LBS: true, LBU: true, LHS: true, LHU: true, LW: true, } } func (this *Instruction) EdriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LD: true, } } func (this *Instruction) EriiOpCodes() map[OpCode]bool { return map[OpCode]bool{ SB: true, SB_ID: true, SD: true, SD_ID: true, SH: true, SH_ID: true, SW: true, SW_ID: true, } } func (this *Instruction) ErirOpCodes() map[OpCode]bool { return map[OpCode]bool{ SB: true, SH: true, SW: true, } } func (this *Instruction) EridOpCodes() map[OpCode]bool { return map[OpCode]bool{ SD: true, } } func (this *Instruction) LdmaDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LDMA: true, } } func (this *Instruction) LdmaiDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ LDMAI: true, } } func (this *Instruction) SdmaDmaRriOpCodes() map[OpCode]bool { return map[OpCode]bool{ SDMA: true, } } func (this *Instruction) DmaRriOpCodes() map[OpCode]bool { ldma_dma_rri_op_codes := this.LdmaDmaRriOpCodes() ldmai_dma_rri_op_codes := this.LdmaiDmaRriOpCodes() sdma_dma_rri_op_codes := this.SdmaDmaRriOpCodes() dma_rri_op_codes := make(map[OpCode]bool) for k, v := range ldma_dma_rri_op_codes { dma_rri_op_codes[k] = v } for k, v := range ldmai_dma_rri_op_codes { dma_rri_op_codes[k] = v } for k, v := range sdma_dma_rri_op_codes { dma_rri_op_codes[k] = v } return dma_rri_op_codes } func (this *Instruction) Stringify() string { str := this.StringifyOpCode() + ", " str += this.StringifySuffix() + ", " if this.suffix == RICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == RRIC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRICI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRIF { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == RRRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ZRIC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRIF { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRR { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == ZRRC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRRCI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == S_RRIC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRIF { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == S_RRRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == U_RRIC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRIF { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == U_RRRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == RRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZR { str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == ZRC { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZRCI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == S_RRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RR { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == U_RRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == DRDICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyPairRegDescriptor(this.db) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RRRI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == RRRICI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZRRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ZRRICI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RRRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == S_RRRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RRRI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == U_RRRICI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == RIR { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == RIRC { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == RIRCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ZIR { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) } else if this.suffix == ZIRC { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == ZIRCI { str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_RIRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == S_RIRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_RIRC { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) } else if this.suffix == U_RIRCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyImm(this.imm) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == R { str += this.StringifyGpRegDescriptor(this.rc) } else if this.suffix == RCI { str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == Z { str = str[:len(str)-2] } else if this.suffix == ZCI { str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == S_R { str += this.StringifyPairRegDescriptor(this.dc) } else if this.suffix == S_RCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == U_R { str += this.StringifyPairRegDescriptor(this.dc) } else if this.suffix == U_RCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == CI { str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == I { str += this.StringifyImm(this.imm) } else if this.suffix == DDCI { str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifyPairRegDescriptor(this.db) + ", " str += this.StringifyCondition(*this.condition) + ", " str += this.StringifyPc(this.pc) } else if this.suffix == ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyGpRegDescriptor(this.rc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == S_ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == U_ERRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == EDRI { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifyPairRegDescriptor(this.dc) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) } else if this.suffix == ERII { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifyImm(this.imm) } else if this.suffix == ERIR { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifySrcRegDescriptor(this.rb) } else if this.suffix == ERID { str += this.StringifyEndian(*this.endian) + ", " str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifyOff(this.off) + ", " str += this.StringifyPairRegDescriptor(this.db) } else if this.suffix == DMA_RRI { str += this.StringifySrcRegDescriptor(this.ra) + ", " str += this.StringifySrcRegDescriptor(this.rb) + ", " str += this.StringifyImm(this.imm) } else { err := errors.New("suffix is not valid") panic(err) } return str } func (this *Instruction) StringifyOpCode() string { if this.op_code == ACQUIRE { return "acquire" } else if this.op_code == RELEASE { return "release" } else if this.op_code == RELEASE { return "release" } else if this.op_code == ADD { return "add" } else if this.op_code == ADDC { return "addc" } else if this.op_code == AND { return "and" } else if this.op_code == ANDN { return "andn" } else if this.op_code == ASR { return "asr" } else if this.op_code == CAO { return "cao" } else if this.op_code == CLO { return "clo" } else if this.op_code == CLS { return "cls" } else if this.op_code == CLZ { return "clz" } else if this.op_code == CMPB4 { return "cmpb4" } else if this.op_code == DIV_STEP { return "div_step" } else if this.op_code == EXTSB { return "extsb" } else if this.op_code == EXTSH { return "extsh" } else if this.op_code == EXTUB { return "extub" } else if this.op_code == EXTUH { return "extuh" } else if this.op_code == LSL { return "lsl" } else if this.op_code == LSL_ADD { return "lsl_add" } else if this.op_code == LSL_SUB { return "lsl_sub" } else if this.op_code == LSL1 { return "lsl1" } else if this.op_code == LSL1X { return "lsl1x" } else if this.op_code == LSLX { return "lslx" } else if this.op_code == LSR { return "lsr" } else if this.op_code == LSR_ADD { return "lsr_add" } else if this.op_code == LSR1 { return "lsr1" } else if this.op_code == LSR1X { return "lsr1x" } else if this.op_code == LSRX { return "lsrx" } else if this.op_code == MUL_SH_SH { return "mul_sh_sh" } else if this.op_code == MUL_SH_SL { return "mul_sh_sl" } else if this.op_code == MUL_SH_UH { return "mul_sh_uh" } else if this.op_code == MUL_SH_UL { return "mul_sh_ul" } else if this.op_code == MUL_SL_SH { return "mul_sl_sh" } else if this.op_code == MUL_SL_SL { return "mul_sl_sl" } else if this.op_code == MUL_SL_UH { return "mul_sl_uh" } else if this.op_code == MUL_SL_UL { return "mul_sl_ul" } else if this.op_code == MUL_STEP { return "mul_step" } else if this.op_code == MUL_UH_UH { return "mul_uh_uh" } else if this.op_code == MUL_UH_UL { return "mul_uh_ul" } else if this.op_code == MUL_UL_UH { return "mul_ul_uh" } else if this.op_code == MUL_UL_UL { return "mul_ul_ul" } else if this.op_code == NAND { return "nand" } else if this.op_code == NOR { return "nor" } else if this.op_code == NXOR { return "nxor" } else if this.op_code == OR { return "or" } else if this.op_code == ORN { return "orn" } else if this.op_code == ROL { return "rol" } else if this.op_code == ROL_ADD { return "rol_add" } else if this.op_code == ROR { return "ror" } else if this.op_code == RSUB { return "rsub" } else if this.op_code == RSUBC { return "rsubc" } else if this.op_code == SUB { return "sub" } else if this.op_code == SUBC { return "subc" } else if this.op_code == XOR { return "xor" } else if this.op_code == BOOT { return "boot" } else if this.op_code == RESUME { return "resume" } else if this.op_code == STOP { return "stop" } else if this.op_code == CALL { return "call" } else if this.op_code == FAULT { return "fault" } else if this.op_code == NOP { return "nop" } else if this.op_code == SATS { return "sats" } else if this.op_code == MOVD { return "movd" } else if this.op_code == SWAPD { return "swapd" } else if this.op_code == HASH { return "hash" } else if this.op_code == TIME { return "time" } else if this.op_code == TIME_CFG { return "time_cfg" } else if this.op_code == LBS { return "lbs" } else if this.op_code == LBU { return "lbu" } else if this.op_code == LD { return "ld" } else if this.op_code == LHS { return "lhs" } else if this.op_code == LHU { return "lhu" } else if this.op_code == LW { return "lw" } else if this.op_code == SB { return "sb" } else if this.op_code == SB_ID { return "sb_id" } else if this.op_code == SD { return "sd" } else if this.op_code == SD_ID { return "sd_id" } else if this.op_code == SH { return "sh" } else if this.op_code == SH_ID { return "sh_id" } else if this.op_code == SW { return "sw" } else if this.op_code == SW_ID { return "sw_id" } else if this.op_code == LDMA { return "ldma" } else if this.op_code == LDMAI { return "ldmai" } else if this.op_code == SDMA { return "sdma" } else { err := errors.New("op code is not valid") panic(err) } } func (this *Instruction) StringifySuffix() string { if this.suffix == RICI { return "rici" } else if this.suffix == RRI { return "rri" } else if this.suffix == RRIC { return "rric" } else if this.suffix == RRICI { return "rrici" } else if this.suffix == RRIF { return "rrif" } else if this.suffix == RRR { return "rrr" } else if this.suffix == RRRC { return "rrrc" } else if this.suffix == RRRCI { return "rrrci" } else if this.suffix == ZRI { return "zri" } else if this.suffix == ZRIC { return "zric" } else if this.suffix == ZRICI { return "zrici" } else if this.suffix == ZRIF { return "zrif" } else if this.suffix == ZRR { return "zrr" } else if this.suffix == ZRRC { return "zrrc" } else if this.suffix == ZRRCI { return "zrrci" } else if this.suffix == S_RRI { return "s_rri" } else if this.suffix == S_RRIC { return "s_rric" } else if this.suffix == S_RRICI { return "s_rrici" } else if this.suffix == S_RRIF { return "s_rrif" } else if this.suffix == S_RRR { return "s_rrr" } else if this.suffix == S_RRRC { return "s_rrrc" } else if this.suffix == S_RRRCI { return "s_rrrci" } else if this.suffix == U_RRI { return "u_rri" } else if this.suffix == U_RRIC { return "u_rric" } else if this.suffix == U_RRICI { return "u_rrici" } else if this.suffix == U_RRIF { return "u_rrif" } else if this.suffix == U_RRR { return "u_rrr" } else if this.suffix == U_RRRC { return "u_rrrc" } else if this.suffix == U_RRRCI { return "u_rrrci" } else if this.suffix == RR { return "rr" } else if this.suffix == RRC { return "rrc" } else if this.suffix == RRCI { return "rrci" } else if this.suffix == ZR { return "zr" } else if this.suffix == ZRC { return "zrc" } else if this.suffix == ZRCI { return "zrci" } else if this.suffix == S_RR { return "s_rr" } else if this.suffix == S_RRC { return "s_rrc" } else if this.suffix == S_RRCI { return "s_rrci" } else if this.suffix == U_RR { return "u_rr" } else if this.suffix == U_RRC { return "u_rrc" } else if this.suffix == U_RRCI { return "u_rrci" } else if this.suffix == DRDICI { return "drdici" } else if this.suffix == RRRI { return "rrri" } else if this.suffix == RRRICI { return "rrrici" } else if this.suffix == ZRRI { return "zrri" } else if this.suffix == ZRRICI { return "zrrici" } else if this.suffix == S_RRRI { return "s_rrri" } else if this.suffix == S_RRRICI { return "s_rrrici" } else if this.suffix == U_RRRI { return "u_rrri" } else if this.suffix == U_RRRICI { return "u_rrrici" } else if this.suffix == RIR { return "rir" } else if this.suffix == RIRC { return "rirc" } else if this.suffix == RIRCI { return "rirci" } else if this.suffix == ZIR { return "zir" } else if this.suffix == ZIRC { return "zirc" } else if this.suffix == ZIRCI { return "zirci" } else if this.suffix == S_RIRC { return "s_zirc" } else if this.suffix == S_RIRCI { return "s_zirci" } else if this.suffix == U_RIRC { return "u_zirc" } else if this.suffix == U_RIRCI { return "u_zirci" } else if this.suffix == R { return "r" } else if this.suffix == RCI { return "rci" } else if this.suffix == Z { return "z" } else if this.suffix == ZCI { return "zci" } else if this.suffix == S_R { return "s_r" } else if this.suffix == S_RCI { return "s_rci" } else if this.suffix == U_R { return "u_r" } else if this.suffix == U_RCI { return "u_rci" } else if this.suffix == CI { return "ci" } else if this.suffix == I { return "i" } else if this.suffix == DDCI { return "ddci" } else if this.suffix == ERRI { return "erri" } else if this.suffix == S_ERRI { return "s_erri" } else if this.suffix == U_ERRI { return "u_erri" } else if this.suffix == EDRI { return "edri" } else if this.suffix == ERII { return "erii" } else if this.suffix == ERIR { return "erir" } else if this.suffix == ERID { return "erid" } else if this.suffix == DMA_RRI { return "dma_rri" } else { err := errors.New("suffix is not valid") panic(err) } } func (this *Instruction) StringifyGpRegDescriptor( gp_reg_descriptor *reg_descriptor.GpRegDescriptor, ) string { return "r" + strconv.Itoa(gp_reg_descriptor.Index()) } func (this *Instruction) StringifySrcRegDescriptor( src_reg_descriptor *reg_descriptor.SrcRegDescriptor, ) string { if src_reg_descriptor.IsGpRegDescriptor() { return this.StringifyGpRegDescriptor(src_reg_descriptor.GpRegDescriptor()) } else { sp_reg_descriptor := src_reg_descriptor.SpRegDescriptor() if *sp_reg_descriptor == reg_descriptor.ZERO { return "zero" } else if *sp_reg_descriptor == reg_descriptor.ONE { return "one" } else if *sp_reg_descriptor == reg_descriptor.LNEG { return "lneg" } else if *sp_reg_descriptor == reg_descriptor.MNEG { return "mneg" } else if *sp_reg_descriptor == reg_descriptor.ID { return "id" } else if *sp_reg_descriptor == reg_descriptor.ID2 { return "id2" } else if *sp_reg_descriptor == reg_descriptor.ID4 { return "id4" } else if *sp_reg_descriptor == reg_descriptor.ID8 { return "id8" } else { err := errors.New("sp reg descriptor is not valid") panic(err) } } } func (this *Instruction) StringifyPairRegDescriptor( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, ) string { return "d" + strconv.Itoa(pair_reg_descriptor.Index()) } func (this *Instruction) StringifyImm(imm *abi.Immediate) string { return strconv.FormatInt(imm.Value(), 10) } func (this *Instruction) StringifyCondition(condition cc.Condition) string { if condition == cc.TRUE { return "true" } else if condition == cc.FALSE { return "false" } else if condition == cc.Z { return "z" } else if condition == cc.NZ { return "nz" } else if condition == cc.E { return "e" } else if condition == cc.O { return "o" } else if condition == cc.PL { return "pl" } else if condition == cc.MI { return "mi" } else if condition == cc.OV { return "ov" } else if condition == cc.NOV { return "nov" } else if condition == cc.C { return "c" } else if condition == cc.NC { return "nc" } else if condition == cc.SZ { return "sz" } else if condition == cc.SNZ { return "snz" } else if condition == cc.SPL { return "spl" } else if condition == cc.SMI { return "smi" } else if condition == cc.SO { return "so" } else if condition == cc.SE { return "se" } else if condition == cc.NC5 { return "nc5" } else if condition == cc.NC6 { return "nc6" } else if condition == cc.NC7 { return "nc7" } else if condition == cc.NC8 { return "nc8" } else if condition == cc.NC9 { return "nc9" } else if condition == cc.NC10 { return "nc10" } else if condition == cc.NC11 { return "nc11" } else if condition == cc.NC12 { return "nc12" } else if condition == cc.NC13 { return "nc13" } else if condition == cc.NC14 { return "nc14" } else if condition == cc.MAX { return "max" } else if condition == cc.NMAX { return "nmax" } else if condition == cc.SH32 { return "sh32" } else if condition == cc.NSH32 { return "nsh32" } else if condition == cc.EQ { return "eq" } else if condition == cc.NEQ { return "neq" } else if condition == cc.LTU { return "ltu" } else if condition == cc.LEU { return "leu" } else if condition == cc.GTU { return "gtu" } else if condition == cc.GEU { return "geu" } else if condition == cc.LTS { return "lts" } else if condition == cc.LES { return "les" } else if condition == cc.GTS { return "gts" } else if condition == cc.GES { return "ges" } else if condition == cc.XZ { return "xz" } else if condition == cc.XNZ { return "xnz" } else if condition == cc.XLEU { return "xleu" } else if condition == cc.XGTU { return "xgtu" } else if condition == cc.XLES { return "xles" } else if condition == cc.XGTS { return "xgts" } else if condition == cc.SMALL { return "small" } else if condition == cc.LARGE { return "large" } else { err := errors.New("condition is not valid") panic(err) } } func (this *Instruction) StringifyEndian(endian Endian) string { if endian == LITTLE { return "!little" } else if endian == BIG { return "!big" } else { err := errors.New("endian is not valid") panic(err) } } func (this *Instruction) StringifyOff(off *abi.Immediate) string { return strconv.FormatInt(off.Value(), 10) } func (this *Instruction) StringifyPc(pc *abi.Immediate) string { return strconv.FormatInt(pc.Value(), 10) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/op_code.go ================================================ package instruction type OpCode int const ( ACQUIRE OpCode = iota RELEASE ADD ADDC AND ANDN ASR CAO CLO CLS CLZ CMPB4 DIV_STEP EXTSB EXTSH EXTUB EXTUH LSL LSL_ADD LSL_SUB LSL1 LSL1X LSLX LSR LSR_ADD LSR1 LSR1X LSRX MUL_SH_SH MUL_SH_SL MUL_SH_UH MUL_SH_UL MUL_SL_SH MUL_SL_SL MUL_SL_UH MUL_SL_UL MUL_STEP MUL_UH_UH MUL_UH_UL MUL_UL_UH MUL_UL_UL NAND NOR NXOR OR ORN ROL ROL_ADD ROR RSUB RSUBC SUB SUBC XOR BOOT RESUME STOP CALL FAULT NOP SATS MOVD SWAPD HASH TIME TIME_CFG LBS LBU LD LHS LHU LW SB SB_ID SD SD_ID SH SH_ID SW SW_ID LDMA LDMAI SDMA ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/reg_descriptor/gp_reg_descriptor.go ================================================ package reg_descriptor import ( "errors" "uPIMulator/src/misc" ) type GpRegDescriptor struct { index int } func (this *GpRegDescriptor) Init(index int) { if index < 0 { err := errors.New("index < 0") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() if index >= config_loader.NumGpRegisters() { err := errors.New("index >= num gp registers") panic(err) } this.index = index } func (this *GpRegDescriptor) Index() int { return this.index } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/reg_descriptor/pair_reg_descriptor.go ================================================ package reg_descriptor import ( "errors" ) type PairRegDescriptor struct { even_reg_descriptor *GpRegDescriptor odd_reg_descriptor *GpRegDescriptor } func (this *PairRegDescriptor) Init(index int) { if index%2 != 0 { err := errors.New("index %2 != 0") panic(err) } this.even_reg_descriptor = new(GpRegDescriptor) this.even_reg_descriptor.Init(index) this.odd_reg_descriptor = new(GpRegDescriptor) this.odd_reg_descriptor.Init(index + 1) } func (this *PairRegDescriptor) Index() int { return this.even_reg_descriptor.Index() } func (this *PairRegDescriptor) EvenRegDescriptor() *GpRegDescriptor { return this.even_reg_descriptor } func (this *PairRegDescriptor) OddRegDescriptor() *GpRegDescriptor { return this.odd_reg_descriptor } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/reg_descriptor/sp_reg_descriptor.go ================================================ package reg_descriptor type SpRegDescriptor int const ( ZERO SpRegDescriptor = iota ONE LNEG MNEG ID ID2 ID4 ID8 ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/reg_descriptor/src_reg_descriptor.go ================================================ package reg_descriptor type SrcRegDescriptor struct { gp_reg_descriptor *GpRegDescriptor sp_reg_descriptor *SpRegDescriptor } func (this *SrcRegDescriptor) InitGpRegDescriptor(gp_reg_descriptor *GpRegDescriptor) { this.gp_reg_descriptor = gp_reg_descriptor this.sp_reg_descriptor = nil } func (this *SrcRegDescriptor) InitSpRegDescriptor(sp_reg_descriptor *SpRegDescriptor) { this.gp_reg_descriptor = nil this.sp_reg_descriptor = sp_reg_descriptor } func (this *SrcRegDescriptor) IsGpRegDescriptor() bool { return this.gp_reg_descriptor != nil } func (this *SrcRegDescriptor) IsSpRegDescriptor() bool { return this.sp_reg_descriptor != nil } func (this *SrcRegDescriptor) GpRegDescriptor() *GpRegDescriptor { return this.gp_reg_descriptor } func (this *SrcRegDescriptor) SpRegDescriptor() *SpRegDescriptor { return this.sp_reg_descriptor } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/instruction/suffix.go ================================================ package instruction type Suffix int const ( RICI Suffix = iota RRI RRIC RRICI RRIF RRR RRRC RRRCI ZRI ZRIC ZRICI ZRIF ZRR ZRRC ZRRCI S_RRI S_RRIC S_RRICI S_RRIF S_RRR S_RRRC S_RRRCI U_RRI U_RRIC U_RRICI U_RRIF U_RRR U_RRRC U_RRRCI RR RRC RRCI ZR ZRC ZRCI S_RR S_RRC S_RRCI U_RR U_RRC U_RRCI DRDICI RRRI RRRICI ZRRI ZRRICI S_RRRI S_RRRICI U_RRRI U_RRRICI RIR RIRC RIRCI ZIR ZIRC ZIRCI S_RIRC S_RIRCI U_RIRC U_RIRCI R RCI Z ZCI S_R S_RCI U_R U_RCI CI I DDCI ERRI S_ERRI U_ERRI EDRI ERII ERIR ERID DMA_RRI ) ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/kernel.go ================================================ package kernel import ( "errors" "uPIMulator/src/encoding" ) type Kernel struct { addresses map[string]int64 atomic *encoding.ByteStream iram *encoding.ByteStream wram *encoding.ByteStream mram *encoding.ByteStream } func (this *Kernel) Init() { this.addresses = make(map[string]int64) } func (this *Kernel) Address(label_name string) int64 { if address, found := this.addresses[label_name]; found { return address } else { err := errors.New("address is not found") panic(err) } } func (this *Kernel) Atomic() *encoding.ByteStream { return this.atomic } func (this *Kernel) SetAtomic(atomic *encoding.ByteStream) { this.atomic = atomic } func (this *Kernel) Iram() *encoding.ByteStream { return this.iram } func (this *Kernel) SetIram(iram *encoding.ByteStream) { this.iram = iram } func (this *Kernel) Wram() *encoding.ByteStream { return this.wram } func (this *Kernel) SetWram(wram *encoding.ByteStream) { this.wram = wram } func (this *Kernel) Mram() *encoding.ByteStream { return this.mram } func (this *Kernel) SetMram(mram *encoding.ByteStream) { this.mram = mram } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/label.go ================================================ package kernel import ( "errors" "uPIMulator/src/encoding" ) type Label struct { name string address *int64 size int64 byte_stream *encoding.ByteStream } func (this *Label) Init(name string) { this.name = name this.address = nil this.size = 0 this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() } func (this *Label) Name() string { return this.name } func (this *Label) Address() int64 { if this.address == nil { err := errors.New("address is not yet set") panic(err) } return *this.address } func (this *Label) BeginAddress() int64 { return this.Address() } func (this *Label) EndAddress() int64 { return this.Address() + this.Size() } func (this *Label) SetAddress(address int64) { if this.address != nil { err := errors.New("address is already set") panic(err) } this.address = new(int64) *this.address = address } func (this *Label) Size() int64 { return this.size } func (this *Label) SetSize(size int64) { this.size = size } func (this *Label) ToByteStream() *encoding.ByteStream { if this.size != this.byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } return this.byte_stream } func (this *Label) Append(encodable Encodable) { this.byte_stream.Merge(encodable.Encode()) if this.byte_stream.Size() > this.size { err := errors.New("byte stream's size > size") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/liveness.go ================================================ package kernel type Liveness struct { defs map[string]bool uses map[string]bool global_symbols map[string]bool } func (this *Liveness) Init() { this.defs = make(map[string]bool) this.uses = make(map[string]bool) this.global_symbols = make(map[string]bool) } func (this *Liveness) Defs() map[string]bool { return this.defs } func (this *Liveness) AddDef(def string) { this.defs[def] = true } func (this *Liveness) Uses() map[string]bool { return this.uses } func (this *Liveness) AddUse(use string) { this.uses[use] = true } func (this *Liveness) GlobalSymbols() map[string]bool { return this.global_symbols } func (this *Liveness) AddGlobalSymbol(global_symbol string) { this.global_symbols[global_symbol] = true } func (this *Liveness) LocalSymbols() map[string]bool { local_symbols := make(map[string]bool) for def, _ := range this.defs { if _, found := this.global_symbols[def]; !found { local_symbols[def] = true } } return local_symbols } func (this *Liveness) UnresolvedSymbols() map[string]bool { unresolved_symbols := make(map[string]bool) for use, _ := range this.uses { if _, found := this.defs[use]; !found { unresolved_symbols[use] = true } } return unresolved_symbols } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/relocatable.go ================================================ package kernel import ( "errors" "strings" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/misc" ) type Relocatable struct { name string path string token_stream *lexer.TokenStream ast *parser.Ast liveness *Liveness renames map[string]string } func (this *Relocatable) Init(name string) { this.name = name this.renames = make(map[string]string) } func (this *Relocatable) Name() string { return this.name } func (this *Relocatable) Path() string { return this.path } func (this *Relocatable) SetPath(path string) { this.path = path } func (this *Relocatable) TokenStream() *lexer.TokenStream { return this.token_stream } func (this *Relocatable) SetTokenStream(token_stream *lexer.TokenStream) { this.token_stream = token_stream } func (this *Relocatable) Ast() *parser.Ast { return this.ast } func (this *Relocatable) SetAst(ast *parser.Ast) { this.ast = ast } func (this *Relocatable) Liveness() *Liveness { return this.liveness } func (this *Relocatable) SetLiveness(liveness *Liveness) { this.liveness = liveness } func (this *Relocatable) Lines() []string { file_scanner := new(misc.FileScanner) file_scanner.Init(this.path) lines := file_scanner.ReadLines() for i, line := range lines { lines[i] = this.RenameLine(line) } return lines } func (this *Relocatable) RenameLocalSymbol(old_name string, new_name string) { if _, found := this.liveness.LocalSymbols()[old_name]; !found { err := errors.New("local symbol is not found") panic(err) } if rename, found := this.renames[old_name]; found { if rename != new_name { err := errors.New("rename is already set") panic(err) } } this.renames[old_name] = new_name } func (this *Relocatable) RenameLine(line string) string { for old_name, new_name := range this.renames { line = strings.ReplaceAll(line, old_name+",", new_name+",") line = strings.ReplaceAll(line, old_name+" ", new_name+" ") line = strings.ReplaceAll(line, old_name+"\t", new_name+"\t") line = strings.ReplaceAll(line, old_name+":", new_name+":") line = strings.ReplaceAll(line, old_name+"+", new_name+"+") line = strings.ReplaceAll(line, old_name+"-", new_name+"-") if len(line) > len(old_name) { pos := len(line) - len(old_name) if line[pos:] == old_name { line = line[:pos] + new_name } } } return line } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/kernel/section.go ================================================ package kernel import ( "errors" "uPIMulator/src/encoding" ) type SectionName int const ( ATOMIC SectionName = iota BSS DATA DEBUG_ABBREV DEBUG_FRAME DEBUG_INFO DEBUG_LINE DEBUG_LOC DEBUG_RANGES DEBUG_STR DPU_HOST MRAM RODATA STACK_SIZES TEXT ) type SectionFlag int const ( ALLOC SectionFlag = iota WRITE EXECINSTR LINK_ORDER MERGE STRINGS ) type SectionType int const ( PROGBITS SectionType = iota NOBITS ) type Section struct { section_name SectionName name string section_flags map[SectionFlag]bool section_type SectionType labels []*Label cur_label *Label } func (this *Section) Init( section_name SectionName, name string, section_flags map[SectionFlag]bool, section_type SectionType, ) { this.section_name = section_name this.name = name this.section_flags = section_flags this.section_type = section_type default_label := new(Label) default_label.Init(this.HiddenLabelName()) this.labels = make([]*Label, 0) this.labels = append(this.labels, default_label) this.cur_label = default_label } func (this *Section) SectionName() SectionName { return this.section_name } func (this *Section) Name() string { return this.name } func (this *Section) SectionFlags() map[SectionFlag]bool { return this.section_flags } func (this *Section) SectionType() SectionType { return this.section_type } func (this *Section) Address() int64 { return this.labels[0].Address() } func (this *Section) SetAddress(address int64) { cur_address := address for _, label := range this.labels { label.SetAddress(cur_address) cur_address += label.Size() } } func (this *Section) Size() int64 { size := int64(0) for _, label := range this.labels { size += label.Size() } return size } func (this *Section) Label(label_name string) *Label { for _, label := range this.labels { if label.Name() == label_name { return label } } return nil } func (this *Section) Labels() []*Label { return this.labels } func (this *Section) AppendLabel(label_name string) { label := new(Label) label.Init(label_name) this.labels = append(this.labels, label) } func (this *Section) CheckoutLabel(label_name string) { if this.Label(label_name) == nil { err := errors.New("label is not found") panic(err) } this.cur_label = this.Label(label_name) } func (this *Section) CurLabel() *Label { return this.cur_label } func (this *Section) ToByteStream() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, label := range this.labels { byte_stream.Merge(label.ToByteStream()) } return byte_stream } func (this *Section) HiddenLabelName() string { if this.section_name == ATOMIC { return "atomic." + this.name } else if this.section_name == BSS { return "bss." + this.name } else if this.section_name == DATA { return "data." + this.name } else if this.section_name == DEBUG_ABBREV { return "debug_abbrev." + this.name } else if this.section_name == DEBUG_FRAME { return "debug_frame." + this.name } else if this.section_name == DEBUG_INFO { return "debug_info." + this.name } else if this.section_name == DEBUG_LINE { return "debug_line." + this.name } else if this.section_name == DEBUG_LOC { return "debug_loc." + this.name } else if this.section_name == DEBUG_RANGES { return "debug_ranges." + this.name } else if this.section_name == DEBUG_STR { return "debug_str." + this.name } else if this.section_name == DPU_HOST { return "dpu_host." + this.name } else if this.section_name == MRAM { return "mram." + this.name } else if this.section_name == RODATA { return "rodata." + this.name } else if this.section_name == STACK_SIZES { return "stack_sizes." + this.name } else if this.section_name == TEXT { return "text." + this.name } else { err := errors.New("section name is not valid") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lex_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/lexer" ) type LexJob struct { relocatable *kernel.Relocatable } func (this *LexJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *LexJob) Execute() { fmt.Printf("Lexing %s...\n", this.relocatable.Path()) lexer_ := new(lexer.Lexer) lexer_.Init() token_stream := lexer_.Lex(this.relocatable.Path()) this.relocatable.SetTokenStream(token_stream) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/keyword_factory.go ================================================ package lexer import ( "errors" ) type KeywordFactory struct { keywords map[string]TokenType } func (this *KeywordFactory) Init() { this.keywords = make(map[string]TokenType) } func (this *KeywordFactory) AddKeyword(keyword string, token_type TokenType) { this.keywords[keyword] = token_type } func (this *KeywordFactory) IsTokenizable(word string) bool { _, found := this.keywords[word] return found } func (this *KeywordFactory) Tokenize(word string) *Token { if _, found := this.keywords[word]; !found { err := errors.New("word is not tokenizable") panic(err) } token_type := this.keywords[word] token := new(Token) token.Init(token_type, "") return token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/lexer.go ================================================ package lexer import ( "errors" "uPIMulator/src/misc" ) type Lexer struct { tokenizer *Tokenizer } func (this *Lexer) Init() { this.tokenizer = new(Tokenizer) this.tokenizer.Init() } func (this *Lexer) Lex(path string) *TokenStream { file_scanner := new(misc.FileScanner) file_scanner.Init(path) token_stream := new(TokenStream) token_stream.Init() for _, line := range file_scanner.ReadLines() { token_stream.Merge(this.Tokenize(line)) new_line := new(Token) new_line.Init(NEW_LINE, "") token_stream.Append(new_line) } end_of_file := new(Token) end_of_file.Init(END_OF_FILE, "") token_stream.Append(end_of_file) return token_stream } func (this *Lexer) Tokenize(line string) *TokenStream { token_stream := new(TokenStream) token_stream.Init() prev_pos := 0 for prev_pos < len(line) { token, length := this.FindTokenWithMaxLength(line, prev_pos) if token != nil { token_stream.Append(token) } prev_pos += length } return token_stream } func (this *Lexer) FindTokenWithMaxLength(line string, prev_pos int) (*Token, int) { if prev_pos < 0 { err := errors.New("prev pos < 0") panic(err) } if this.IsWhiteSpace(string(line[prev_pos])) { return nil, 1 } if prev_pos+2 < len(line) && this.IsComment(line[prev_pos:prev_pos+2]) { return nil, len(line) - prev_pos } if this.IsQuote(string(line[prev_pos])) { next_quote_pos := this.FindNextQuote(line, prev_pos+1) word := line[prev_pos : next_quote_pos+1] token := this.tokenizer.Tokenize(word) return token, next_quote_pos - prev_pos + 1 } for i := prev_pos + 1; i <= len(line); i++ { word := line[prev_pos:i] if i+1 <= len(line) { next_word := line[prev_pos : i+1] if this.tokenizer.IsTokenizable(word) && !this.tokenizer.IsTokenizable(next_word) { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } } else { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } } err := errors.New("line is not further tokenizable") panic(err) } func (this *Lexer) IsWhiteSpace(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == " " || word == "\t" || word == "\n" } func (this *Lexer) IsComment(word string) bool { if len(word) != 2 { err := errors.New("word size != 2") panic(err) } return word == "//" } func (this *Lexer) IsQuote(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == "\"" } func (this *Lexer) FindNextQuote(line string, pos int) int { for i := pos; i < len(line); i++ { if this.IsQuote(string(line[i])) { return i } } err := errors.New("line does not have the next quote") panic(err) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/regex.go ================================================ package lexer import ( "errors" "regexp" ) type Regex struct { expr string regex *regexp.Regexp token_type TokenType } func (this *Regex) Init(expr string, token_type TokenType) { this.expr = expr regex, err := regexp.Compile(expr) if err != nil { panic(err) } this.regex = regex this.token_type = token_type } func (this *Regex) Expr() string { return this.expr } func (this *Regex) TokenType() TokenType { return this.token_type } func (this *Regex) IsTokenizable(word string) bool { return this.regex.MatchString(word) } func (this *Regex) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not matched") panic(err) } token := new(Token) token.Init(this.token_type, word) return token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/regex_factory.go ================================================ package lexer import ( "errors" ) type RegexFactory struct { regexes []*Regex } func (this *RegexFactory) Init() { this.regexes = make([]*Regex, 0) } func (this *RegexFactory) HasRegex(expr string) bool { for _, regex := range this.regexes { if regex.Expr() == expr { return true } } return false } func (this *RegexFactory) AddRegex(expr string, token_type TokenType) { if this.HasRegex(expr) { err := errors.New("regex already exists") panic(err) } regex := new(Regex) regex.Init(expr, token_type) this.regexes = append(this.regexes, regex) } func (this *RegexFactory) IsTokenizable(word string) bool { for _, regex := range this.regexes { if regex.IsTokenizable(word) { return true } } return false } func (this *RegexFactory) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not tokenizable") panic(err) } for _, regex := range this.regexes { if regex.IsTokenizable(word) { token := new(Token) token.Init(regex.TokenType(), word) return token } } return nil } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/token.go ================================================ package lexer type TokenType int const ( END_OF_FILE TokenType = iota NEW_LINE IDENTIFIER POSITIVIE_NUMBER HEX_NUMBER STRING GP_REG PAIR_REG ACQUIRE RELEASE BOOT RESUME ADD ADDC AND ANDN ASR CMPB4 LSL LSL1 LSL1X LSLX LSR LSR1 LSR1X LSRX MUL_SH_SH MUL_SH_SL MUL_SH_UH MUL_SH_UL MUL_SL_SH MUL_SL_SL MUL_SL_UH MUL_SL_UL MUL_UH_UH MUL_UH_UL MUL_UL_UH MUL_UL_UL NAND NOR NXOR OR ORN ROL ROR RSUB RSUBC SUB SUBC XOR CALL HASH CAO CLO CLS CLZ EXTSB EXTSH EXTUB EXTUH SATS TIME_CFG DIV_STEP MUL_STEP LSL_ADD LSL_SUB LSR_ADD ROL_ADD TIME NOP STOP FAULT MOVD SWAPD LBS LBU LD LHS LHU LW SB SB_ID SD SD_ID SH SH_ID SW SW_ID LDMA LDMAI SDMA MOVE NEG NOT BKP JEQ JNEQ JZ JNZ JLTU JGTU JLEU JGEU JLTS JGTS JLES JGES JUMP S U ATOMIC BSS DATA DEBUG_ABBREV DEBUG_FRAME DEBUG_INFO DEBUG_LINE DEBUG_LOC DEBUG_RANGES DEBUG_STR DPU_HOST MRAM RODATA STACK_SIZES TEXT PROGBITS NOBITS FUNCTION OBJECT TRUE FALSE Z NZ E O PL MI OV NOV C NC SZ SNZ SPL SMI SO SE NC5 NC6 NC7 NC8 NC9 NC10 NC11 NC12 NC13 NC14 MAX NMAX SH32 NSH32 EQ NEQ LTU LEU GTU GEU LTS LES GTS GES XZ XNZ XLEU XGTU XLES XGTS SMALL LARGE LITTLE BIG ZERO_REG ONE ID ID2 ID4 ID8 LNEG MNEG ADDRSIG ADDRSIG_SYM ASCII ASCIZ BYTE CFI_DEF_CFA_OFFSET CFI_ENDPROC CFI_OFFSET CFI_SECTIONS CFI_STARTPROC FILE GLOBL LOC LONG P2ALIGN QUAD SECTION SET SHORT SIZE TYPE WEAK ZERO_DIRECTIVE IS_STMT PROLOGUE_END COLON COMMA PLUS MINUS ) type Token struct { token_type TokenType attribute string } func (this *Token) Init(token_type TokenType, attribute string) { this.token_type = token_type this.attribute = attribute } func (this *Token) TokenType() TokenType { return this.token_type } func (this *Token) Attribute() string { return this.attribute } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/token_stream.go ================================================ package lexer type TokenStream struct { tokens []*Token } func (this *TokenStream) Init() { this.tokens = make([]*Token, 0) } func (this *TokenStream) Length() int { return len(this.tokens) } func (this *TokenStream) Get(pos int) *Token { return this.tokens[pos] } func (this *TokenStream) Append(token *Token) { this.tokens = append(this.tokens, token) } func (this *TokenStream) Merge(token_stream *TokenStream) { for i := 0; i < token_stream.Length(); i++ { this.Append(token_stream.Get(i)) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/lexer/tokenizer.go ================================================ package lexer import ( "errors" ) type Tokenizer struct { keyword_factory *KeywordFactory regex_factory *RegexFactory } func (this *Tokenizer) Init() { this.InitKeywordFactory() this.InitRegexFactory() } func (this *Tokenizer) InitKeywordFactory() { this.keyword_factory = new(KeywordFactory) this.keyword_factory.Init() this.keyword_factory.AddKeyword("acquire", ACQUIRE) this.keyword_factory.AddKeyword("release", RELEASE) this.keyword_factory.AddKeyword("boot", BOOT) this.keyword_factory.AddKeyword("resume", RESUME) this.keyword_factory.AddKeyword("add", ADD) this.keyword_factory.AddKeyword("addc", ADDC) this.keyword_factory.AddKeyword("and", AND) this.keyword_factory.AddKeyword("andn", ANDN) this.keyword_factory.AddKeyword("asr", ASR) this.keyword_factory.AddKeyword("cmpb4", CMPB4) this.keyword_factory.AddKeyword("lsl", LSL) this.keyword_factory.AddKeyword("lsl1", LSL1) this.keyword_factory.AddKeyword("lsl1x", LSL1X) this.keyword_factory.AddKeyword("lslx", LSLX) this.keyword_factory.AddKeyword("lsr", LSR) this.keyword_factory.AddKeyword("lsr1", LSR1) this.keyword_factory.AddKeyword("lsr1x", LSR1X) this.keyword_factory.AddKeyword("lsrx", LSRX) this.keyword_factory.AddKeyword("mul_sh_sh", MUL_SH_SH) this.keyword_factory.AddKeyword("mul_sh_sl", MUL_SH_SL) this.keyword_factory.AddKeyword("mul_sh_uh", MUL_SH_UH) this.keyword_factory.AddKeyword("mul_sh_ul", MUL_SH_UL) this.keyword_factory.AddKeyword("mul_sl_sh", MUL_SL_SH) this.keyword_factory.AddKeyword("mul_sl_sl", MUL_SL_SL) this.keyword_factory.AddKeyword("mul_sl_uh", MUL_SL_UH) this.keyword_factory.AddKeyword("mul_sl_ul", MUL_SL_UL) this.keyword_factory.AddKeyword("mul_uh_uh", MUL_UH_UH) this.keyword_factory.AddKeyword("mul_uh_ul", MUL_UH_UL) this.keyword_factory.AddKeyword("mul_ul_uh", MUL_UL_UH) this.keyword_factory.AddKeyword("mul_ul_ul", MUL_UL_UL) this.keyword_factory.AddKeyword("nand", NAND) this.keyword_factory.AddKeyword("nor", NOR) this.keyword_factory.AddKeyword("nxor", NXOR) this.keyword_factory.AddKeyword("or", OR) this.keyword_factory.AddKeyword("orn", ORN) this.keyword_factory.AddKeyword("rol", ROL) this.keyword_factory.AddKeyword("ror", ROR) this.keyword_factory.AddKeyword("rsub", RSUB) this.keyword_factory.AddKeyword("rsubc", RSUBC) this.keyword_factory.AddKeyword("sub", SUB) this.keyword_factory.AddKeyword("subc", SUBC) this.keyword_factory.AddKeyword("xor", XOR) this.keyword_factory.AddKeyword("call", CALL) this.keyword_factory.AddKeyword("hash", HASH) this.keyword_factory.AddKeyword("cao", CAO) this.keyword_factory.AddKeyword("clo", CLO) this.keyword_factory.AddKeyword("cls", CLS) this.keyword_factory.AddKeyword("clz", CLZ) this.keyword_factory.AddKeyword("extsb", EXTSB) this.keyword_factory.AddKeyword("extsh", EXTSH) this.keyword_factory.AddKeyword("extub", EXTUB) this.keyword_factory.AddKeyword("extuh", EXTUH) this.keyword_factory.AddKeyword("sats", SATS) this.keyword_factory.AddKeyword("time_cfg", TIME_CFG) this.keyword_factory.AddKeyword("div_step", DIV_STEP) this.keyword_factory.AddKeyword("mul_step", MUL_STEP) this.keyword_factory.AddKeyword("lsl_add", LSL_ADD) this.keyword_factory.AddKeyword("lsl_sub", LSL_SUB) this.keyword_factory.AddKeyword("lsr_add", LSR_ADD) this.keyword_factory.AddKeyword("rol_add", ROL_ADD) this.keyword_factory.AddKeyword("time", TIME) this.keyword_factory.AddKeyword("nop", NOP) this.keyword_factory.AddKeyword("stop", STOP) this.keyword_factory.AddKeyword("fault", FAULT) this.keyword_factory.AddKeyword("movd", MOVD) this.keyword_factory.AddKeyword("swapd", SWAPD) this.keyword_factory.AddKeyword("lbs", LBS) this.keyword_factory.AddKeyword("lbu", LBU) this.keyword_factory.AddKeyword("ld", LD) this.keyword_factory.AddKeyword("lhs", LHS) this.keyword_factory.AddKeyword("lhu", LHU) this.keyword_factory.AddKeyword("lw", LW) this.keyword_factory.AddKeyword("sb", SB) this.keyword_factory.AddKeyword("sb_id", SB_ID) this.keyword_factory.AddKeyword("sd", SD) this.keyword_factory.AddKeyword("sd_id", SD_ID) this.keyword_factory.AddKeyword("sh", SH) this.keyword_factory.AddKeyword("sh_id", SH_ID) this.keyword_factory.AddKeyword("sw", SW) this.keyword_factory.AddKeyword("sw_id", SW_ID) this.keyword_factory.AddKeyword("ldma", LDMA) this.keyword_factory.AddKeyword("ldmai", LDMAI) this.keyword_factory.AddKeyword("sdma", SDMA) this.keyword_factory.AddKeyword("move", MOVE) this.keyword_factory.AddKeyword("neg", NEG) this.keyword_factory.AddKeyword("not", NOT) this.keyword_factory.AddKeyword("bkp", BKP) this.keyword_factory.AddKeyword("jeq", JEQ) this.keyword_factory.AddKeyword("jneq", JNEQ) this.keyword_factory.AddKeyword("jz", JZ) this.keyword_factory.AddKeyword("jnz", JNZ) this.keyword_factory.AddKeyword("jltu", JLTU) this.keyword_factory.AddKeyword("jgtu", JGTU) this.keyword_factory.AddKeyword("jleu", JLEU) this.keyword_factory.AddKeyword("jgeu", JGEU) this.keyword_factory.AddKeyword("jlts", JLTS) this.keyword_factory.AddKeyword("jgts", JGTS) this.keyword_factory.AddKeyword("jles", JLES) this.keyword_factory.AddKeyword("jges", JGES) this.keyword_factory.AddKeyword("jump", JUMP) this.keyword_factory.AddKeyword(".s", S) this.keyword_factory.AddKeyword(".u", U) this.keyword_factory.AddKeyword(".atomic", ATOMIC) this.keyword_factory.AddKeyword(".bss", BSS) this.keyword_factory.AddKeyword(".data", DATA) this.keyword_factory.AddKeyword(".debug_abbrev", DEBUG_ABBREV) this.keyword_factory.AddKeyword(".debug_frame", DEBUG_FRAME) this.keyword_factory.AddKeyword(".debug_info", DEBUG_INFO) this.keyword_factory.AddKeyword(".debug_line", DEBUG_LINE) this.keyword_factory.AddKeyword(".debug_loc", DEBUG_LOC) this.keyword_factory.AddKeyword(".debug_ranges", DEBUG_RANGES) this.keyword_factory.AddKeyword(".debug_str", DEBUG_STR) this.keyword_factory.AddKeyword(".dpu_host", DPU_HOST) this.keyword_factory.AddKeyword(".mram", MRAM) this.keyword_factory.AddKeyword(".rodata", RODATA) this.keyword_factory.AddKeyword(".stack_sizes", STACK_SIZES) this.keyword_factory.AddKeyword(".text", TEXT) this.keyword_factory.AddKeyword(".file", FILE) this.keyword_factory.AddKeyword(".section", SECTION) this.keyword_factory.AddKeyword("@progbits", PROGBITS) this.keyword_factory.AddKeyword("@nobits", NOBITS) this.keyword_factory.AddKeyword("@function", FUNCTION) this.keyword_factory.AddKeyword("@object", OBJECT) this.keyword_factory.AddKeyword("true", TRUE) this.keyword_factory.AddKeyword("false", FALSE) this.keyword_factory.AddKeyword("z", Z) this.keyword_factory.AddKeyword("nz", NZ) this.keyword_factory.AddKeyword("e", E) this.keyword_factory.AddKeyword("o", O) this.keyword_factory.AddKeyword("pl", PL) this.keyword_factory.AddKeyword("mi", MI) this.keyword_factory.AddKeyword("ov", OV) this.keyword_factory.AddKeyword("nov", NOV) this.keyword_factory.AddKeyword("c", C) this.keyword_factory.AddKeyword("nc", NC) this.keyword_factory.AddKeyword("sz", SZ) this.keyword_factory.AddKeyword("snz", SNZ) this.keyword_factory.AddKeyword("spl", SPL) this.keyword_factory.AddKeyword("smi", SMI) this.keyword_factory.AddKeyword("so", SO) this.keyword_factory.AddKeyword("se", SE) this.keyword_factory.AddKeyword("nc5", NC5) this.keyword_factory.AddKeyword("nc6", NC6) this.keyword_factory.AddKeyword("nc7", NC7) this.keyword_factory.AddKeyword("nc8", NC8) this.keyword_factory.AddKeyword("nc9", NC9) this.keyword_factory.AddKeyword("nc10", NC10) this.keyword_factory.AddKeyword("nc11", NC11) this.keyword_factory.AddKeyword("nc12", NC12) this.keyword_factory.AddKeyword("nc13", NC13) this.keyword_factory.AddKeyword("nc14", NC14) this.keyword_factory.AddKeyword("max", MAX) this.keyword_factory.AddKeyword("nmax", NMAX) this.keyword_factory.AddKeyword("sh32", SH32) this.keyword_factory.AddKeyword("nsh32", NSH32) this.keyword_factory.AddKeyword("eq", EQ) this.keyword_factory.AddKeyword("neq", NEQ) this.keyword_factory.AddKeyword("ltu", LTU) this.keyword_factory.AddKeyword("leu", LEU) this.keyword_factory.AddKeyword("gtu", GTU) this.keyword_factory.AddKeyword("geu", GEU) this.keyword_factory.AddKeyword("lts", LTS) this.keyword_factory.AddKeyword("les", LES) this.keyword_factory.AddKeyword("gts", GTS) this.keyword_factory.AddKeyword("ges", GES) this.keyword_factory.AddKeyword("xz", XZ) this.keyword_factory.AddKeyword("xnz", XNZ) this.keyword_factory.AddKeyword("xleu", XLEU) this.keyword_factory.AddKeyword("xgtu", XGTU) this.keyword_factory.AddKeyword("xles", XLES) this.keyword_factory.AddKeyword("xgts", XGTS) this.keyword_factory.AddKeyword("small", SMALL) this.keyword_factory.AddKeyword("large", LARGE) this.keyword_factory.AddKeyword("!little", LITTLE) this.keyword_factory.AddKeyword("!big", BIG) this.keyword_factory.AddKeyword("zero", ZERO_REG) this.keyword_factory.AddKeyword("one", ONE) this.keyword_factory.AddKeyword("id", ID) this.keyword_factory.AddKeyword("id2", ID2) this.keyword_factory.AddKeyword("id4", ID4) this.keyword_factory.AddKeyword("id8", ID8) this.keyword_factory.AddKeyword("lneg", LNEG) this.keyword_factory.AddKeyword("mneg", MNEG) this.keyword_factory.AddKeyword(".addrsig", ADDRSIG) this.keyword_factory.AddKeyword(".addrsig_sym", ADDRSIG_SYM) this.keyword_factory.AddKeyword(".ascii", ASCII) this.keyword_factory.AddKeyword(".asciz", ASCIZ) this.keyword_factory.AddKeyword(".byte", BYTE) this.keyword_factory.AddKeyword(".cfi_def_cfa_offset", CFI_DEF_CFA_OFFSET) this.keyword_factory.AddKeyword(".cfi_endproc", CFI_ENDPROC) this.keyword_factory.AddKeyword(".cfi_offset", CFI_OFFSET) this.keyword_factory.AddKeyword(".cfi_sections", CFI_SECTIONS) this.keyword_factory.AddKeyword(".cfi_startproc", CFI_STARTPROC) this.keyword_factory.AddKeyword(".globl", GLOBL) this.keyword_factory.AddKeyword(".loc", LOC) this.keyword_factory.AddKeyword(".long", LONG) this.keyword_factory.AddKeyword(".p2align", P2ALIGN) this.keyword_factory.AddKeyword(".quad", QUAD) this.keyword_factory.AddKeyword(".set", SET) this.keyword_factory.AddKeyword(".short", SHORT) this.keyword_factory.AddKeyword(".size", SIZE) this.keyword_factory.AddKeyword(".type", TYPE) this.keyword_factory.AddKeyword(".weak", WEAK) this.keyword_factory.AddKeyword(".zero", ZERO_DIRECTIVE) this.keyword_factory.AddKeyword("is_stmt", IS_STMT) this.keyword_factory.AddKeyword("prologue_end", PROLOGUE_END) this.keyword_factory.AddKeyword(":", COLON) this.keyword_factory.AddKeyword(",", COMMA) this.keyword_factory.AddKeyword("+", PLUS) this.keyword_factory.AddKeyword("-", MINUS) } func (this *Tokenizer) InitRegexFactory() { this.regex_factory = new(RegexFactory) this.regex_factory.Init() this.regex_factory.AddRegex("^(r)([0-9]*)$", GP_REG) this.regex_factory.AddRegex("^(d)([0-9]*)$", PAIR_REG) this.regex_factory.AddRegex("^([A-Za-z_.])([A-Za-z0-9_]*)$", IDENTIFIER) this.regex_factory.AddRegex("^([0-9]*)$", POSITIVIE_NUMBER) this.regex_factory.AddRegex("^(0x)([0-9]*)$", HEX_NUMBER) this.regex_factory.AddRegex("^(\")(.*)(\")$", STRING) } func (this *Tokenizer) IsTokenizable(word string) bool { return this.keyword_factory.IsTokenizable(word) || this.regex_factory.IsTokenizable(word) } func (this *Tokenizer) Tokenize(word string) *Token { if this.keyword_factory.IsTokenizable(word) { return this.keyword_factory.Tokenize(word) } else if this.regex_factory.IsTokenizable(word) { return this.regex_factory.Tokenize(word) } else { err := errors.New("word is not tokenizable") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/linker.go ================================================ package linker import ( "fmt" "os" "path/filepath" "uPIMulator/src/device/core" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/logic" "uPIMulator/src/device/linker/parser" "uPIMulator/src/misc" ) type Linker struct { root_dirpath string bin_dirpath string benchmark string benchmark_relocatable *kernel.Relocatable sdk_relocatables map[string]*kernel.Relocatable executable *kernel.Executable linker_script *logic.LinkerScript } func (this *Linker) Init(command_line_parser *misc.CommandLineParser) { this.root_dirpath = command_line_parser.StringParameter("root_dirpath") this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") this.InitBenchmarkRelocatable() this.InitSdkRelocatables() this.executable = new(kernel.Executable) this.executable.Init(this.benchmark) this.linker_script = new(logic.LinkerScript) this.linker_script.Init(command_line_parser) } func (this *Linker) InitBenchmarkRelocatable() { benchmark_build_dirpath := filepath.Join(this.root_dirpath, "benchmark", "build") assembly_path := filepath.Join( benchmark_build_dirpath, this.benchmark, "dpu", "CMakeFiles", fmt.Sprintf("%s_device.dir", this.benchmark), "task.c.o", ) this.benchmark_relocatable = new(kernel.Relocatable) this.benchmark_relocatable.Init(this.benchmark) this.benchmark_relocatable.SetPath(assembly_path) } func (this *Linker) InitSdkRelocatables() { this.sdk_relocatables = make(map[string]*kernel.Relocatable) sdk_build_dirpath := filepath.Join(this.root_dirpath, "sdk", "build") sdk_build_dir_entries, sdk_build_dir_read_err := os.ReadDir(sdk_build_dirpath) if sdk_build_dir_read_err != nil { panic(sdk_build_dir_read_err) } for _, sdk_build_dir_entry := range sdk_build_dir_entries { if sdk_build_dir_entry.IsDir() && sdk_build_dir_entry.Name() != "CMakeFiles" { sdk_lib_dirpath := filepath.Join( sdk_build_dirpath, sdk_build_dir_entry.Name(), "CMakeFiles", sdk_build_dir_entry.Name()+".dir", ) sdk_lib_dir_entries, sdk_lib_dir_read_err := os.ReadDir(sdk_lib_dirpath) if sdk_lib_dir_read_err != nil { panic(sdk_lib_dir_read_err) } for _, sdk_lib_dir_entry := range sdk_lib_dir_entries { assembly_path := filepath.Join(sdk_lib_dirpath, sdk_lib_dir_entry.Name()) lib_dir_name := filepath.Base(sdk_lib_dirpath) sdk_relocatable_name := lib_dir_name[:len(lib_dir_name)-4] + "." + sdk_lib_dir_entry.Name()[:len(sdk_lib_dir_entry.Name())-4] sdk_relocatable := new(kernel.Relocatable) sdk_relocatable.Init(sdk_relocatable_name) sdk_relocatable.SetPath(assembly_path) this.sdk_relocatables[sdk_relocatable_name] = sdk_relocatable } } } } func (this *Linker) Link() { this.Lex() this.Parse() this.AnalyzeLiveness() this.MakeExecutable() this.LoadExecutable() this.DumpExecutable() } func (this *Linker) Lex() { thread_pool := new(core.ThreadPool) thread_pool.Init() benchmark_lex_job := new(LexJob) benchmark_lex_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_lex_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_lex_job := new(LexJob) sdk_lex_job.Init(sdk_relocatable) thread_pool.Enque(sdk_lex_job) } thread_pool.Start() } func (this *Linker) Parse() { thread_pool := new(core.ThreadPool) thread_pool.Init() benchmark_parse_job := new(ParseJob) benchmark_parse_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_parse_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_parse_job := new(ParseJob) sdk_parse_job.Init(sdk_relocatable) thread_pool.Enque(sdk_parse_job) } thread_pool.Start() } func (this *Linker) AnalyzeLiveness() { thread_pool := new(core.ThreadPool) thread_pool.Init() benchmark_analyze_liveness_job := new(AnalyzeLivenessJob) benchmark_analyze_liveness_job.Init(this.benchmark_relocatable) thread_pool.Enque(benchmark_analyze_liveness_job) for _, sdk_relocatable := range this.sdk_relocatables { sdk_analyze_liveness_job := new(AnalyzeLivenessJob) sdk_analyze_liveness_job.Init(sdk_relocatable) thread_pool.Enque(sdk_analyze_liveness_job) } thread_pool.Start() } func (this *Linker) MakeExecutable() { fmt.Printf("Resolving symbols of %s...\n", this.executable.Name()) this.executable.SetBenchmarkRelocatable(this.benchmark_relocatable) this.ResolveSymbols() executable_path := filepath.Join(this.bin_dirpath, "main.S") fmt.Printf("Dumping the executable to %s...\n", this.executable.Path()) this.executable.SetPath(executable_path) this.executable.DumpAssembly() } func (this *Linker) HasResolved() bool { for unresolved_symbol, _ := range this.executable.Liveness().UnresolvedSymbols() { if !this.linker_script.HasLinkerConstant(unresolved_symbol) { return false } } return true } func (this *Linker) ResolveSymbols() { this.executable.AddSdkRelocatable(this.sdk_relocatables["misc.crt0"]) for !this.HasResolved() { for unresolved_symbol, _ := range this.executable.Liveness().UnresolvedSymbols() { if !this.linker_script.HasLinkerConstant(unresolved_symbol) { for _, sdk_relocatable := range this.sdk_relocatables { if _, found := sdk_relocatable.Liveness().GlobalSymbols()[unresolved_symbol]; found { this.executable.AddSdkRelocatable(sdk_relocatable) } } } } } } func (this *Linker) LoadExecutable() { fmt.Println("Re-lexing executable") lexer_ := new(lexer.Lexer) lexer_.Init() token_stream := lexer_.Lex(this.executable.Path()) this.executable.SetTokenStream(token_stream) fmt.Println("Re-parsing executable...") parser_ := new(parser.Parser) parser_.Init() ast := parser_.Parse(token_stream) this.executable.SetAst(ast) fmt.Println("Assigning labels...") label_assigner := new(logic.LabelAssigner) label_assigner.Init() label_assigner.Assign(this.executable) fmt.Println("Assigning addresses..") this.linker_script.Assign(this.executable) fmt.Println("Setting alias labels...") set_assigner := new(logic.SetAssigner) set_assigner.Init() set_assigner.Assign(this.executable) fmt.Println("Assigning instructions...") instruction_assigner := new(logic.InstructionAssigner) instruction_assigner.Init(this.linker_script) instruction_assigner.Assign(this.executable) } func (this *Linker) DumpExecutable() { this.linker_script.DumpValues(filepath.Join(this.bin_dirpath, "values.txt")) this.executable.DumpAddresses(filepath.Join(this.bin_dirpath, "addresses.txt")) this.executable.DumpAtomic(filepath.Join(this.bin_dirpath, "atomic.bin")) this.executable.DumpIram(filepath.Join(this.bin_dirpath, "iram.bin")) this.executable.DumpWram(filepath.Join(this.bin_dirpath, "wram.bin")) this.executable.DumpMram(filepath.Join(this.bin_dirpath, "mram.bin")) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/instruction_assigner.go ================================================ package logic import ( "errors" "strconv" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/kernel/directive" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/device/linker/kernel/instruction/cc" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" "uPIMulator/src/misc" ) type InstructionAssigner struct { executable *kernel.Executable walker *parser.Walker linker_script *LinkerScript } func (this *InstructionAssigner) Init(linker_script *LinkerScript) { this.linker_script = linker_script this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback(stmt.ASCII, this.WalkAsciiStmt) this.walker.RegisterStmtCallback(stmt.ASCIZ, this.WalkAscizStmt) this.walker.RegisterStmtCallback(stmt.BYTE, this.WalkByteStmt) this.walker.RegisterStmtCallback(stmt.LONG_PROGRAM_COUNTER, this.WalkLongProgramCounterStmt) this.walker.RegisterStmtCallback(stmt.LONG_SECTION_NAME, this.WalkLongSectionNameStmt) this.walker.RegisterStmtCallback(stmt.QUAD, this.WalkQuadStmt) this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.SHORT, this.WalkShortStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) this.walker.RegisterStmtCallback(stmt.ZERO_DOUBLE_NUMBER, this.WalkZeroDoubleNumberStmt) this.walker.RegisterStmtCallback(stmt.ZERO_SINGLE_NUMBER, this.WalkZeroSingleNumberStmt) this.walker.RegisterStmtCallback(stmt.CI, this.WalkCiStmt) this.walker.RegisterStmtCallback(stmt.DMA_RRI, this.WalkDmaRriStmt) this.walker.RegisterStmtCallback(stmt.DRDICI, this.WalkDrdiciStmt) this.walker.RegisterStmtCallback(stmt.EDRI, this.WalkEdriStmt) this.walker.RegisterStmtCallback(stmt.ERID, this.WalkEridStmt) this.walker.RegisterStmtCallback(stmt.ERII, this.WalkEriiStmt) this.walker.RegisterStmtCallback(stmt.ERIR, this.WalkErirStmt) this.walker.RegisterStmtCallback(stmt.ERRI, this.WalkErriStmt) this.walker.RegisterStmtCallback(stmt.I, this.WalkIStmt) this.walker.RegisterStmtCallback(stmt.NOP, this.WalkNopStmt) this.walker.RegisterStmtCallback(stmt.RCI, this.WalkRciStmt) this.walker.RegisterStmtCallback(stmt.RICI, this.WalkRiciStmt) this.walker.RegisterStmtCallback(stmt.RIRCI, this.WalkRirciStmt) this.walker.RegisterStmtCallback(stmt.RIRC, this.WalkRircStmt) this.walker.RegisterStmtCallback(stmt.RIR, this.WalkRirStmt) this.walker.RegisterStmtCallback(stmt.RRCI, this.WalkRrciStmt) this.walker.RegisterStmtCallback(stmt.RRC, this.WalkRrcStmt) this.walker.RegisterStmtCallback(stmt.RRICI, this.WalkRriciStmt) this.walker.RegisterStmtCallback(stmt.RRIC, this.WalkRricStmt) this.walker.RegisterStmtCallback(stmt.RRI, this.WalkRriStmt) this.walker.RegisterStmtCallback(stmt.RRRCI, this.WalkRrrciStmt) this.walker.RegisterStmtCallback(stmt.RRRC, this.WalkRrrcStmt) this.walker.RegisterStmtCallback(stmt.RRRICI, this.WalkRrriciStmt) this.walker.RegisterStmtCallback(stmt.RRRI, this.WalkRrriStmt) this.walker.RegisterStmtCallback(stmt.RRR, this.WalkRrrStmt) this.walker.RegisterStmtCallback(stmt.RR, this.WalkRrStmt) this.walker.RegisterStmtCallback(stmt.R, this.WalkRStmt) this.walker.RegisterStmtCallback(stmt.S_ERRI, this.WalkSErriStmt) this.walker.RegisterStmtCallback(stmt.S_RCI, this.WalkSRciStmt) this.walker.RegisterStmtCallback(stmt.S_RIRCI, this.WalkSRirciStmt) this.walker.RegisterStmtCallback(stmt.S_RIRC, this.WalkSRircStmt) this.walker.RegisterStmtCallback(stmt.S_RRCI, this.WalkSRrciStmt) this.walker.RegisterStmtCallback(stmt.S_RRC, this.WalkSRrcStmt) this.walker.RegisterStmtCallback(stmt.S_RRICI, this.WalkSRriciStmt) this.walker.RegisterStmtCallback(stmt.S_RRIC, this.WalkSRricStmt) this.walker.RegisterStmtCallback(stmt.S_RRI, this.WalkSRriStmt) this.walker.RegisterStmtCallback(stmt.S_RRRCI, this.WalkSRrrciStmt) this.walker.RegisterStmtCallback(stmt.S_RRRC, this.WalkSRrrcStmt) this.walker.RegisterStmtCallback(stmt.S_RRRICI, this.WalkSRrriciStmt) this.walker.RegisterStmtCallback(stmt.S_RRRI, this.WalkSRrriStmt) this.walker.RegisterStmtCallback(stmt.S_RRR, this.WalkSRrrStmt) this.walker.RegisterStmtCallback(stmt.S_RR, this.WalkSRrStmt) this.walker.RegisterStmtCallback(stmt.S_R, this.WalkSRStmt) this.walker.RegisterStmtCallback(stmt.BKP, this.WalkBkpStmt) this.walker.RegisterStmtCallback(stmt.BOOT_RI, this.WalkBootRiStmt) this.walker.RegisterStmtCallback(stmt.CALL_RI, this.WalkCallRiStmt) this.walker.RegisterStmtCallback(stmt.CALL_RR, this.WalkCallRrStmt) this.walker.RegisterStmtCallback(stmt.DIV_STEP_DRDI, this.WalkDivStepDrdiStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RII, this.WalkJeqRiiStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RRI, this.WalkJeqRriStmt) this.walker.RegisterStmtCallback(stmt.JNZ_RI, this.WalkJnzRiStmt) this.walker.RegisterStmtCallback(stmt.JUMP_I, this.WalkJumpIStmt) this.walker.RegisterStmtCallback(stmt.JUMP_R, this.WalkJumpRStmt) this.walker.RegisterStmtCallback(stmt.LBS_RRI, this.WalkLbsRriStmt) this.walker.RegisterStmtCallback(stmt.LBS_S_RRI, this.WalkLbsSRriStmt) this.walker.RegisterStmtCallback(stmt.LD_DRI, this.WalkLdDriStmt) this.walker.RegisterStmtCallback(stmt.MOVD_DD, this.WalkMovdDdStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RICI, this.WalkMoveRiciStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RI, this.WalkMoveRiStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RICI, this.WalkMoveSRiciStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RI, this.WalkMoveSRiStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RII, this.WalkSbIdRiiStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RI, this.WalkSbIdRiStmt) this.walker.RegisterStmtCallback(stmt.SB_RIR, this.WalkSbRirStmt) this.walker.RegisterStmtCallback(stmt.SD_RID, this.WalkSdRidStmt) this.walker.RegisterStmtCallback(stmt.STOP, this.WalkStopStmt) this.walker.RegisterStmtCallback(stmt.TIME_CFG_R, this.WalkTimeCfgRStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *InstructionAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *InstructionAssigner) WalkAsciiStmt(stmt_ *stmt.Stmt) { ascii_stmt := stmt_.AsciiStmt() token := ascii_stmt.Token() attribute := token.Attribute() characters := attribute[1 : len(attribute)-1] // TODO(bongjoon.hyun@gmail.com): decode octal code ascii_directive := new(directive.AsciiDirective) ascii_directive.Init(characters) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(ascii_directive) } func (this *InstructionAssigner) WalkAscizStmt(stmt_ *stmt.Stmt) { asciz_stmt := stmt_.AscizStmt() token := asciz_stmt.Token() attribute := token.Attribute() characters := attribute[1 : len(attribute)-1] asciz_directive := new(directive.AscizDirective) asciz_directive.Init(characters) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(asciz_directive) } func (this *InstructionAssigner) WalkByteStmt(stmt_ *stmt.Stmt) { byte_stmt := stmt_.ByteStmt() value := this.EvaluateProgramCounter(byte_stmt.Expr()) byte_directive := new(directive.ByteDirective) byte_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(byte_directive) } func (this *InstructionAssigner) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { long_program_counter_stmt := stmt_.LongProgramCounterStmt() value := this.EvaluateProgramCounter(long_program_counter_stmt.Expr()) long_directive := new(directive.LongDirective) long_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(long_directive) } func (this *InstructionAssigner) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { long_section_name_stmt := stmt_.LongSectionNameStmt() value := this.EvaluateSectionName(long_section_name_stmt.Expr()) long_directive := new(directive.LongDirective) long_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(long_directive) } func (this *InstructionAssigner) WalkQuadStmt(stmt_ *stmt.Stmt) { quad_stmt := stmt_.QuadStmt() value := this.EvaluateProgramCounter(quad_stmt.Expr()) quad_directive := new(directive.QuadDirective) quad_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(quad_directive) } func (this *InstructionAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkShortStmt(stmt_ *stmt.Stmt) { short_stmt := stmt_.ShortStmt() value := this.EvaluateProgramCounter(short_stmt.Expr()) short_directive := new(directive.ShortDirective) short_directive.Init(value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(short_directive) } func (this *InstructionAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" this.executable.CheckoutSection(section_name, name) } func (this *InstructionAssigner) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() size := this.EvaluateProgramCounter(zero_double_number_stmt.Expr1()) value := this.EvaluateProgramCounter(zero_double_number_stmt.Expr2()) zero_directive := new(directive.ZeroDirective) zero_directive.Init(size, value) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(zero_directive) } func (this *InstructionAssigner) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() size := this.EvaluateProgramCounter(zero_single_number_stmt.Expr()) zero_directive := new(directive.ZeroDirective) zero_directive.Init(size, 0) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(zero_directive) } func (this *InstructionAssigner) WalkCiStmt(stmt_ *stmt.Stmt) { ci_stmt := stmt_.CiStmt() op_code := this.ConvertCiOpCode(ci_stmt.OpCode()) condition := this.ConvertCondition(ci_stmt.Condition()) pc := this.EvaluateProgramCounter(ci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitCi(op_code, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDdciStmt(stmt_ *stmt.Stmt) { ddci_stmt := stmt_.DdciStmt() op_code := this.ConvertDdciOpCode(ddci_stmt.OpCode()) dc := this.ConvertPairReg(ddci_stmt.Dc()) db := this.ConvertPairReg(ddci_stmt.Db()) condition := this.ConvertCondition(ddci_stmt.Condition()) pc := this.EvaluateProgramCounter(ddci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitDdci(op_code, dc, db, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDmaRriStmt(stmt_ *stmt.Stmt) { dma_rri_stmt := stmt_.DmaRriStmt() op_code := this.ConvertDmaRriOpCode(dma_rri_stmt.OpCode()) ra := this.ConvertSrcReg(dma_rri_stmt.Ra()) rb := this.ConvertSrcReg(dma_rri_stmt.Rb()) imm := this.EvaluateProgramCounter(dma_rri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitDmaRri(op_code, ra, rb, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDrdiciStmt(stmt_ *stmt.Stmt) { drdici_stmt := stmt_.DrdiciStmt() op_code := this.ConvertDrdiciOpCode(drdici_stmt.OpCode()) dc := this.ConvertPairReg(drdici_stmt.Dc()) ra := this.ConvertSrcReg(drdici_stmt.Ra()) db := this.ConvertPairReg(drdici_stmt.Db()) imm := this.EvaluateProgramCounter(drdici_stmt.Imm()) condition := this.ConvertCondition(drdici_stmt.Condition()) pc := this.EvaluateProgramCounter(drdici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitDrdici(op_code, dc, ra, db, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEdriStmt(stmt_ *stmt.Stmt) { edri_stmt := stmt_.EdriStmt() op_code := this.ConvertLoadOpCode(edri_stmt.OpCode()) endian := this.ConvertEndian(edri_stmt.Endian()) dc := this.ConvertPairReg(edri_stmt.Dc()) ra := this.ConvertSrcReg(edri_stmt.Ra()) off := this.EvaluateProgramCounter(edri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitEdri(op_code, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEridStmt(stmt_ *stmt.Stmt) { erid_stmt := stmt_.EridStmt() op_code := this.ConvertStoreOpCode(erid_stmt.OpCode()) endian := this.ConvertEndian(erid_stmt.Endian()) ra := this.ConvertSrcReg(erid_stmt.Ra()) off := this.EvaluateProgramCounter(erid_stmt.Off()) db := this.ConvertPairReg(erid_stmt.Db()) instruction_ := new(instruction.Instruction) instruction_.InitErid(op_code, endian, ra, off, db) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkEriiStmt(stmt_ *stmt.Stmt) { erii_stmt := stmt_.EriiStmt() op_code := this.ConvertStoreOpCode(erii_stmt.OpCode()) endian := this.ConvertEndian(erii_stmt.Endian()) ra := this.ConvertSrcReg(erii_stmt.Ra()) off := this.EvaluateProgramCounter(erii_stmt.Off()) imm := this.EvaluateProgramCounter(erii_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkErirStmt(stmt_ *stmt.Stmt) { erir_stmt := stmt_.ErirStmt() op_code := this.ConvertStoreOpCode(erir_stmt.OpCode()) endian := this.ConvertEndian(erir_stmt.Endian()) ra := this.ConvertSrcReg(erir_stmt.Ra()) off := this.EvaluateProgramCounter(erir_stmt.Off()) rb := this.ConvertSrcReg(erir_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitErir(op_code, endian, ra, off, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkErriStmt(stmt_ *stmt.Stmt) { erri_stmt := stmt_.ErriStmt() op_code := this.ConvertLoadOpCode(erri_stmt.OpCode()) endian := this.ConvertEndian(erri_stmt.Endian()) rc := this.ConvertGpReg(erri_stmt.Rc()) ra := this.ConvertSrcReg(erri_stmt.Ra()) off := this.EvaluateProgramCounter(erri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitErri(op_code, endian, rc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkIStmt(stmt_ *stmt.Stmt) { i_stmt := stmt_.IStmt() op_code := this.ConvertIOpCode(i_stmt.OpCode()) imm := this.EvaluateProgramCounter(i_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitI(op_code, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkNopStmt(stmt_ *stmt.Stmt) { nop_stmt := stmt_.NopStmt() op_code := this.ConvertROpCode(nop_stmt.OpCode()) instruction_ := new(instruction.Instruction) instruction_.InitZ(op_code) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRciStmt(stmt_ *stmt.Stmt) { rci_stmt := stmt_.RciStmt() is_zero_reg := this.IsZeroReg(rci_stmt.Rc()) op_code := this.ConvertROpCode(rci_stmt.OpCode()) condition := this.ConvertCondition(rci_stmt.Condition()) pc := this.EvaluateProgramCounter(rci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rci_stmt.Rc()) instruction_.InitRci(op_code, rc, condition, pc) } else { instruction_.InitZci(op_code, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRiciStmt(stmt_ *stmt.Stmt) { rici_stmt := stmt_.RiciStmt() op_code := this.ConvertRiciOpCode(rici_stmt.OpCode()) ra := this.ConvertSrcReg(rici_stmt.Ra()) imm := this.EvaluateProgramCounter(rici_stmt.Imm()) condition := this.ConvertCondition(rici_stmt.Condition()) pc := this.EvaluateProgramCounter(rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitRici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRirciStmt(stmt_ *stmt.Stmt) { rirci_stmt := stmt_.RirciStmt() is_zero_reg := this.IsZeroReg(rirci_stmt.Rc()) op_code := this.ConvertRriOpCode(rirci_stmt.OpCode()) imm := this.EvaluateProgramCounter(rirci_stmt.Imm()) ra := this.ConvertSrcReg(rirci_stmt.Ra()) condition := this.ConvertCondition(rirci_stmt.Condition()) pc := this.EvaluateProgramCounter(rirci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rirci_stmt.Rc()) instruction_.InitRirci(op_code, rc, imm, ra, condition, pc) } else { instruction_.InitZirci(op_code, imm, ra, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRircStmt(stmt_ *stmt.Stmt) { rirc_stmt := stmt_.RircStmt() is_zero_reg := this.IsZeroReg(rirc_stmt.Rc()) op_code := this.ConvertRriOpCode(rirc_stmt.OpCode()) imm := this.EvaluateProgramCounter(rirc_stmt.Imm()) ra := this.ConvertSrcReg(rirc_stmt.Ra()) condition := this.ConvertCondition(rirc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rirc_stmt.Rc()) instruction_.InitRirc(op_code, rc, imm, ra, condition) } else { instruction_.InitZirc(op_code, imm, ra, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRirStmt(stmt_ *stmt.Stmt) { rir_stmt := stmt_.RirStmt() is_zero_reg := this.IsZeroReg(rir_stmt.Rc()) op_code := this.ConvertRriOpCode(rir_stmt.OpCode()) imm := this.EvaluateProgramCounter(rir_stmt.Imm()) ra := this.ConvertSrcReg(rir_stmt.Ra()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rir_stmt.Rc()) instruction_.InitRir(op_code, rc, imm, ra) } else { instruction_.InitZir(op_code, imm, ra) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrciStmt(stmt_ *stmt.Stmt) { rrci_stmt := stmt_.RrciStmt() op_code := this.ConvertRrOpCode(rrci_stmt.OpCode()) ra := this.ConvertSrcReg(rrci_stmt.Ra()) condition := this.ConvertCondition(rrci_stmt.Condition()) pc := this.EvaluateProgramCounter(rrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(0) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else if op_code == instruction.SUB { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(0) instruction_.InitRirci(op_code, rc, imm, ra, condition, pc) } else if op_code == instruction.XOR { is_zero_reg := this.IsZeroReg(rrci_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rrci_stmt.Rc()) imm := int64(-1) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else { imm := int64(-1) instruction_.InitZrici(op_code, ra, imm, condition, pc) } } else { is_zero_reg := this.IsZeroReg(rrci_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rrci_stmt.Rc()) instruction_.InitRrci(op_code, rc, ra, condition, pc) } else { instruction_.InitZrci(op_code, ra, condition, pc) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrcStmt(stmt_ *stmt.Stmt) { rrc_stmt := stmt_.RrcStmt() is_zero_reg := this.IsZeroReg(rrc_stmt.Rc()) op_code := this.ConvertRrOpCode(rrc_stmt.OpCode()) ra := this.ConvertSrcReg(rrc_stmt.Ra()) condition := this.ConvertCondition(rrc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrc_stmt.Rc()) instruction_.InitRrc(op_code, rc, ra, condition) } else { instruction_.InitZrc(op_code, ra, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRriciStmt(stmt_ *stmt.Stmt) { rrici_stmt := stmt_.RriciStmt() is_zero_reg := this.IsZeroReg(rrici_stmt.Rc()) op_code := this.ConvertRriOpCode(rrici_stmt.OpCode()) ra := this.ConvertSrcReg(rrici_stmt.Ra()) imm := this.EvaluateProgramCounter(rrici_stmt.Imm()) condition := this.ConvertCondition(rrici_stmt.Condition()) pc := this.EvaluateProgramCounter(rrici_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrici_stmt.Rc()) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) } else { instruction_.InitZrici(op_code, ra, imm, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRricStmt(stmt_ *stmt.Stmt) { rric_stmt := stmt_.RricStmt() is_zero_reg := this.IsZeroReg(rric_stmt.Rc()) op_code := this.ConvertRriOpCode(rric_stmt.OpCode()) ra := this.ConvertSrcReg(rric_stmt.Ra()) imm := this.EvaluateProgramCounter(rric_stmt.Imm()) condition := this.ConvertCondition(rric_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rric_stmt.Rc()) if condition != cc.FALSE { instruction_.InitRric(op_code, rc, ra, imm, condition) } else { instruction_.InitRrif(op_code, rc, ra, imm, condition) } } else { if condition != cc.FALSE { instruction_.InitZric(op_code, ra, imm, condition) } else { instruction_.InitZrif(op_code, ra, imm, condition) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRriStmt(stmt_ *stmt.Stmt) { rri_stmt := stmt_.RriStmt() is_zero_reg := this.IsZeroReg(rri_stmt.Rc()) op_code := this.ConvertRriOpCode(rri_stmt.OpCode()) ra := this.ConvertSrcReg(rri_stmt.Ra()) imm := this.EvaluateProgramCounter(rri_stmt.Imm()) instruction_ := new(instruction.Instruction) if op_code == instruction.ANDN || op_code == instruction.NAND || op_code == instruction.NOR || op_code == instruction.NXOR || op_code == instruction.ORN { rc := this.ConvertGpReg(rri_stmt.Rc()) condition := cc.FALSE instruction_.InitRrif(op_code, rc, ra, imm, condition) } else if !is_zero_reg { rc := this.ConvertGpReg(rri_stmt.Rc()) instruction_.InitRri(op_code, rc, ra, imm) } else { instruction_.InitZri(op_code, ra, imm) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrciStmt(stmt_ *stmt.Stmt) { rrrci_stmt := stmt_.RrrciStmt() is_zero_reg := this.IsZeroReg(rrrci_stmt.Rc()) op_code := this.ConvertRriOpCode(rrrci_stmt.OpCode()) ra := this.ConvertSrcReg(rrrci_stmt.Ra()) rb := this.ConvertSrcReg(rrrci_stmt.Rb()) condition := this.ConvertCondition(rrrci_stmt.Condition()) pc := this.EvaluateProgramCounter(rrrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrci_stmt.Rc()) instruction_.InitRrrci(op_code, rc, ra, rb, condition, pc) } else { instruction_.InitZrrci(op_code, ra, rb, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrcStmt(stmt_ *stmt.Stmt) { rrrc_stmt := stmt_.RrrcStmt() is_zero_reg := this.IsZeroReg(rrrc_stmt.Rc()) op_code := this.ConvertRriOpCode(rrrc_stmt.OpCode()) ra := this.ConvertSrcReg(rrrc_stmt.Ra()) rb := this.ConvertSrcReg(rrrc_stmt.Rb()) condition := this.ConvertCondition(rrrc_stmt.Condition()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrc_stmt.Rc()) instruction_.InitRrrc(op_code, rc, ra, rb, condition) } else { instruction_.InitZrrc(op_code, ra, rb, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrriciStmt(stmt_ *stmt.Stmt) { rrrici_stmt := stmt_.RrriciStmt() is_zero_reg := this.IsZeroReg(rrrici_stmt.Rc()) op_code := this.ConvertRrriOpCode(rrrici_stmt.OpCode()) ra := this.ConvertSrcReg(rrrici_stmt.Ra()) rb := this.ConvertSrcReg(rrrici_stmt.Rb()) imm := this.EvaluateProgramCounter(rrrici_stmt.Imm()) condition := this.ConvertCondition(rrrici_stmt.Condition()) pc := this.EvaluateProgramCounter(rrrici_stmt.Pc()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrrici_stmt.Rc()) instruction_.InitRrrici(op_code, rc, ra, rb, imm, condition, pc) } else { instruction_.InitZrrici(op_code, ra, rb, imm, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrriStmt(stmt_ *stmt.Stmt) { rrri_stmt := stmt_.RrriStmt() is_zero_reg := this.IsZeroReg(rrri_stmt.Rc()) op_code := this.ConvertRrriOpCode(rrri_stmt.OpCode()) ra := this.ConvertSrcReg(rrri_stmt.Ra()) rb := this.ConvertSrcReg(rrri_stmt.Rb()) imm := this.EvaluateProgramCounter(rrri_stmt.Imm()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrri_stmt.Rc()) instruction_.InitRrri(op_code, rc, ra, rb, imm) } else { instruction_.InitZrri(op_code, ra, rb, imm) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrrStmt(stmt_ *stmt.Stmt) { rrr_stmt := stmt_.RrrStmt() is_zero_reg := this.IsZeroReg(rrr_stmt.Rc()) op_code := this.ConvertRriOpCode(rrr_stmt.OpCode()) ra := this.ConvertSrcReg(rrr_stmt.Ra()) rb := this.ConvertSrcReg(rrr_stmt.Rb()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(rrr_stmt.Rc()) instruction_.InitRrr(op_code, rc, ra, rb) } else { instruction_.InitZrr(op_code, ra, rb) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRrStmt(stmt_ *stmt.Stmt) { rr_stmt := stmt_.RrStmt() op_code := this.ConvertRrOpCode(rr_stmt.OpCode()) ra := this.ConvertSrcReg(rr_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(0) condition := cc.FALSE instruction_.InitRrif(op_code, rc, ra, imm, condition) } else if op_code == instruction.SUB { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(0) instruction_.InitRir(op_code, rc, imm, ra) } else if op_code == instruction.XOR { is_zero_reg := this.IsZeroReg(rr_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rr_stmt.Rc()) imm := int64(-1) instruction_.InitRri(op_code, rc, ra, imm) } else { imm := int64(-1) instruction_.InitZri(op_code, ra, imm) } } else { is_zero_reg := this.IsZeroReg(rr_stmt.Rc()) if !is_zero_reg { rc := this.ConvertGpReg(rr_stmt.Rc()) instruction_.InitRr(op_code, rc, ra) } else { instruction_.InitZr(op_code, ra) } } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkRStmt(stmt_ *stmt.Stmt) { r_stmt := stmt_.RStmt() is_zero_reg := this.IsZeroReg(r_stmt.Rc()) op_code := this.ConvertROpCode(r_stmt.OpCode()) instruction_ := new(instruction.Instruction) if !is_zero_reg { rc := this.ConvertGpReg(r_stmt.Rc()) instruction_.InitR(op_code, rc) } else { instruction_.InitZ(op_code) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSErriStmt(stmt_ *stmt.Stmt) { s_erri_stmt := stmt_.SErriStmt() op_code := this.ConvertLoadOpCode(s_erri_stmt.OpCode()) suffix := this.ConvertSuffix(s_erri_stmt.Suffix(), instruction.ERRI) endian := this.ConvertEndian(s_erri_stmt.Endian()) dc := this.ConvertPairReg(s_erri_stmt.Dc()) ra := this.ConvertSrcReg(s_erri_stmt.Ra()) off := this.EvaluateProgramCounter(s_erri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitSErri(op_code, suffix, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRciStmt(stmt_ *stmt.Stmt) { s_rci_stmt := stmt_.SRciStmt() op_code := this.ConvertROpCode(s_rci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rci_stmt.Suffix(), instruction.RCI) dc := this.ConvertPairReg(s_rci_stmt.Dc()) condition := this.ConvertCondition(s_rci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRci(op_code, suffix, dc, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRirciStmt(stmt_ *stmt.Stmt) { s_rirci_stmt := stmt_.SRirciStmt() op_code := this.ConvertRriOpCode(s_rirci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rirci_stmt.Suffix(), instruction.RIRCI) dc := this.ConvertPairReg(s_rirci_stmt.Dc()) imm := this.EvaluateProgramCounter(s_rirci_stmt.Imm()) ra := this.ConvertSrcReg(s_rirci_stmt.Ra()) condition := this.ConvertCondition(s_rirci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rirci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRirci(op_code, suffix, dc, imm, ra, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRircStmt(stmt_ *stmt.Stmt) { s_rirc_stmt := stmt_.SRircStmt() op_code := this.ConvertRriOpCode(s_rirc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rirc_stmt.Suffix(), instruction.RIRC) dc := this.ConvertPairReg(s_rirc_stmt.Dc()) imm := this.EvaluateProgramCounter(s_rirc_stmt.Imm()) ra := this.ConvertSrcReg(s_rirc_stmt.Ra()) condition := this.ConvertCondition(s_rirc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRirc(op_code, suffix, dc, imm, ra, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrciStmt(stmt_ *stmt.Stmt) { s_rrci_stmt := stmt_.SRrciStmt() op_code := this.ConvertRrOpCode(s_rrci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrci_stmt.Suffix(), instruction.RRCI) dc := this.ConvertPairReg(s_rrci_stmt.Dc()) ra := this.ConvertSrcReg(s_rrci_stmt.Ra()) condition := this.ConvertCondition(s_rrci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrci_stmt.Pc()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { if suffix == instruction.S_RRCI { suffix = instruction.S_RRICI imm := int64(0) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) } else { suffix = instruction.U_RRICI imm := int64(0) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) } } else { instruction_.InitSRrci(op_code, suffix, dc, ra, condition, pc) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrcStmt(stmt_ *stmt.Stmt) { s_rrc_stmt := stmt_.SRrcStmt() op_code := this.ConvertRriOpCode(s_rrc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrc_stmt.Suffix(), instruction.RRC) dc := this.ConvertPairReg(s_rrc_stmt.Dc()) ra := this.ConvertSrcReg(s_rrc_stmt.Ra()) condition := this.ConvertCondition(s_rrc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRrc(op_code, suffix, dc, ra, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRriciStmt(stmt_ *stmt.Stmt) { s_rrici_stmt := stmt_.SRriciStmt() op_code := this.ConvertRriOpCode(s_rrici_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrici_stmt.Suffix(), instruction.RRICI) dc := this.ConvertPairReg(s_rrici_stmt.Dc()) ra := this.ConvertSrcReg(s_rrici_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rrici_stmt.Imm()) condition := this.ConvertCondition(s_rrici_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRricStmt(stmt_ *stmt.Stmt) { s_rric_stmt := stmt_.SRricStmt() op_code := this.ConvertRriOpCode(s_rric_stmt.OpCode()) suffix := this.ConvertSuffix(s_rric_stmt.Suffix(), instruction.RRIC) dc := this.ConvertPairReg(s_rric_stmt.Dc()) ra := this.ConvertSrcReg(s_rric_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rric_stmt.Imm()) condition := this.ConvertCondition(s_rric_stmt.Condition()) instruction_ := new(instruction.Instruction) if condition != cc.FALSE { instruction_.InitSRric(op_code, suffix, dc, ra, imm, condition) } else { instruction_.InitSRrif(op_code, suffix, dc, ra, imm, condition) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRriStmt(stmt_ *stmt.Stmt) { s_rri_stmt := stmt_.SRriStmt() op_code := this.ConvertRriOpCode(s_rri_stmt.OpCode()) suffix := this.ConvertSuffix(s_rri_stmt.Suffix(), instruction.RRI) dc := this.ConvertPairReg(s_rri_stmt.Dc()) ra := this.ConvertSrcReg(s_rri_stmt.Ra()) imm := this.EvaluateProgramCounter(s_rri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRri(op_code, suffix, dc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrciStmt(stmt_ *stmt.Stmt) { s_rrrci_stmt := stmt_.SRrrciStmt() op_code := this.ConvertRriOpCode(s_rrrci_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrci_stmt.Suffix(), instruction.RRRCI) dc := this.ConvertPairReg(s_rrrci_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrci_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrci_stmt.Rb()) condition := this.ConvertCondition(s_rrrci_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrrci_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrci(op_code, suffix, dc, ra, rb, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrcStmt(stmt_ *stmt.Stmt) { s_rrrc_stmt := stmt_.SRrrcStmt() op_code := this.ConvertRriOpCode(s_rrrc_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrc_stmt.Suffix(), instruction.RRRC) dc := this.ConvertPairReg(s_rrrc_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrc_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrc_stmt.Rb()) condition := this.ConvertCondition(s_rrrc_stmt.Condition()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrc(op_code, suffix, dc, ra, rb, condition) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrriciStmt(stmt_ *stmt.Stmt) { s_rrrici_stmt := stmt_.SRrriciStmt() op_code := this.ConvertRriOpCode(s_rrrici_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrrici_stmt.Suffix(), instruction.RRRICI) dc := this.ConvertPairReg(s_rrrici_stmt.Dc()) ra := this.ConvertSrcReg(s_rrrici_stmt.Ra()) rb := this.ConvertSrcReg(s_rrrici_stmt.Rb()) imm := this.EvaluateProgramCounter(s_rrrici_stmt.Imm()) condition := this.ConvertCondition(s_rrrici_stmt.Condition()) pc := this.EvaluateProgramCounter(s_rrrici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrrici(op_code, suffix, dc, ra, rb, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrriStmt(stmt_ *stmt.Stmt) { s_rrri_stmt := stmt_.SRrriStmt() op_code := this.ConvertRriOpCode(s_rrri_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrri_stmt.Suffix(), instruction.RRRI) dc := this.ConvertPairReg(s_rrri_stmt.Dc()) ra := this.ConvertSrcReg(s_rrri_stmt.Ra()) rb := this.ConvertSrcReg(s_rrri_stmt.Rb()) imm := this.EvaluateProgramCounter(s_rrri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRrri(op_code, suffix, dc, ra, rb, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrrStmt(stmt_ *stmt.Stmt) { s_rrr_stmt := stmt_.SRrrStmt() op_code := this.ConvertRriOpCode(s_rrr_stmt.OpCode()) suffix := this.ConvertSuffix(s_rrr_stmt.Suffix(), instruction.RRR) dc := this.ConvertPairReg(s_rrr_stmt.Dc()) ra := this.ConvertSrcReg(s_rrr_stmt.Ra()) rb := this.ConvertSrcReg(s_rrr_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitSRrr(op_code, suffix, dc, ra, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRrStmt(stmt_ *stmt.Stmt) { s_rr_stmt := stmt_.SRrStmt() op_code := this.ConvertRrOpCode(s_rr_stmt.OpCode()) suffix := this.ConvertSuffix(s_rr_stmt.Suffix(), instruction.RR) dc := this.ConvertPairReg(s_rr_stmt.Dc()) ra := this.ConvertSrcReg(s_rr_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.OR { if suffix == instruction.S_RR { imm := int64(0) condition := cc.FALSE instruction_.InitSRrif(op_code, instruction.S_RRIF, dc, ra, imm, condition) } else if suffix == instruction.U_RR { imm := int64(0) condition := cc.FALSE instruction_.InitSRrif(op_code, instruction.U_RRIF, dc, ra, imm, condition) } else { err := errors.New("suffix is not valid") panic(err) } } else { instruction_.InitSRr(op_code, suffix, dc, ra) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSRStmt(stmt_ *stmt.Stmt) { s_r_stmt := stmt_.SRStmt() op_code := this.ConvertRriOpCode(s_r_stmt.OpCode()) suffix := this.ConvertSuffix(s_r_stmt.Suffix(), instruction.R) dc := this.ConvertPairReg(s_r_stmt.Dc()) instruction_ := new(instruction.Instruction) instruction_.InitSR(op_code, suffix, dc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkBkpStmt(stmt_ *stmt.Stmt) { op_code := instruction.FAULT imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitI(op_code, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkBootRiStmt(stmt_ *stmt.Stmt) { boot_ri_stmt := stmt_.BootRiStmt() op_code := this.ConvertRiciOpCode(boot_ri_stmt.OpCode()) ra := this.ConvertSrcReg(boot_ri_stmt.Ra()) imm := this.EvaluateProgramCounter(boot_ri_stmt.Imm()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitRici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkCallRiStmt(stmt_ *stmt.Stmt) { call_ri_stmt := stmt_.CallRiStmt() op_code := instruction.CALL rc := this.ConvertGpReg(call_ri_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(call_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkCallRrStmt(stmt_ *stmt.Stmt) { call_rr_stmt := stmt_.CallRrStmt() op_code := instruction.CALL rc := this.ConvertGpReg(call_rr_stmt.Rc()) ra := this.ConvertSrcReg(call_rr_stmt.Ra()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkDivStepDrdiStmt(stmt_ *stmt.Stmt) { div_step_drdi_stmt := stmt_.DivStepDrdiStmt() op_code := this.ConvertDrdiciOpCode(div_step_drdi_stmt.OpCode()) dc := this.ConvertPairReg(div_step_drdi_stmt.Dc()) ra := this.ConvertSrcReg(div_step_drdi_stmt.Ra()) db := this.ConvertPairReg(div_step_drdi_stmt.Db()) imm := this.EvaluateProgramCounter(div_step_drdi_stmt.Imm()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitDrdici(op_code, dc, ra, db, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJeqRiiStmt(stmt_ *stmt.Stmt) { jeq_rii_stmt := stmt_.JeqRiiStmt() op_code := this.ConvertJumpOpCode(jeq_rii_stmt.OpCode()) ra := this.ConvertSrcReg(jeq_rii_stmt.Ra()) imm := this.EvaluateProgramCounter(jeq_rii_stmt.Imm()) condition := this.ConvertJumpCondition(jeq_rii_stmt.OpCode()) pc := this.EvaluateProgramCounter(jeq_rii_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZrici(op_code, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJeqRriStmt(stmt_ *stmt.Stmt) { jeq_rri_stmt := stmt_.JeqRriStmt() op_code := this.ConvertJumpOpCode(jeq_rri_stmt.OpCode()) ra := this.ConvertSrcReg(jeq_rri_stmt.Ra()) rb := this.ConvertSrcReg(jeq_rri_stmt.Rb()) condition := this.ConvertJumpCondition(jeq_rri_stmt.OpCode()) pc := this.EvaluateProgramCounter(jeq_rri_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZrrci(op_code, ra, rb, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJnzRiStmt(stmt_ *stmt.Stmt) { jnz_ri_stmt := stmt_.JnzRiStmt() op_code := this.ConvertJumpOpCode(jnz_ri_stmt.OpCode()) ra := this.ConvertSrcReg(jnz_ri_stmt.Ra()) instruction_ := new(instruction.Instruction) if op_code == instruction.SUB { imm := int64(0) condition := this.ConvertJumpCondition(jnz_ri_stmt.OpCode()) pc := this.EvaluateProgramCounter(jnz_ri_stmt.Pc()) instruction_.InitZrici(op_code, ra, imm, condition, pc) } else if op_code == instruction.CALL { imm := this.EvaluateProgramCounter(jnz_ri_stmt.Pc()) instruction_.InitZri(op_code, ra, imm) } else { err := errors.New("op code is not valid") panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJumpIStmt(stmt_ *stmt.Stmt) { jump_i_stmt := stmt_.JumpIStmt() op_code := instruction.CALL zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(jump_i_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitZri(op_code, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkJumpRStmt(stmt_ *stmt.Stmt) { jump_r_stmt := stmt_.JumpRStmt() op_code := instruction.CALL ra := this.ConvertSrcReg(jump_r_stmt.Ra()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitZri(op_code, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLbsRriStmt(stmt_ *stmt.Stmt) { lbs_rri_stmt := stmt_.LbsRriStmt() op_code := this.ConvertLoadOpCode(lbs_rri_stmt.OpCode()) endian := instruction.LITTLE rc := this.ConvertGpReg(lbs_rri_stmt.Rc()) ra := this.ConvertSrcReg(lbs_rri_stmt.Ra()) off := this.EvaluateProgramCounter(lbs_rri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitErri(op_code, endian, rc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLbsSRriStmt(stmt_ *stmt.Stmt) { lbs_s_rri_stmt := stmt_.LbsSRriStmt() op_code := this.ConvertLoadOpCode(lbs_s_rri_stmt.OpCode()) suffix := this.ConvertSuffix(lbs_s_rri_stmt.Suffix(), instruction.ERRI) endian := instruction.LITTLE dc := this.ConvertPairReg(lbs_s_rri_stmt.Dc()) ra := this.ConvertSrcReg(lbs_s_rri_stmt.Ra()) off := this.EvaluateProgramCounter(lbs_s_rri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitSErri(op_code, suffix, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLdDriStmt(stmt_ *stmt.Stmt) { ld_dri_stmt := stmt_.LdDriStmt() op_code := this.ConvertLoadOpCode(ld_dri_stmt.OpCode()) endian := instruction.LITTLE dc := this.ConvertPairReg(ld_dri_stmt.Dc()) ra := this.ConvertSrcReg(ld_dri_stmt.Ra()) off := this.EvaluateProgramCounter(ld_dri_stmt.Off()) instruction_ := new(instruction.Instruction) instruction_.InitEdri(op_code, endian, dc, ra, off) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMovdDdStmt(stmt_ *stmt.Stmt) { movd_dd_stmt := stmt_.MovdDdStmt() op_code := this.ConvertDdciOpCode(movd_dd_stmt.OpCode()) dc := this.ConvertPairReg(movd_dd_stmt.Dc()) db := this.ConvertPairReg(movd_dd_stmt.Db()) condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitDdci(op_code, dc, db, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveRiciStmt(stmt_ *stmt.Stmt) { move_rici_stmt := stmt_.MoveRiciStmt() op_code := instruction.OR rc := this.ConvertGpReg(move_rici_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_rici_stmt.Imm()) condition := this.ConvertCondition(move_rici_stmt.Condition()) pc := this.EvaluateProgramCounter(move_rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitRrici(op_code, rc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveRiStmt(stmt_ *stmt.Stmt) { move_ri_stmt := stmt_.MoveRiStmt() op_code := instruction.OR rc := this.ConvertGpReg(move_ri_stmt.Rc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitRri(op_code, rc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveSRiciStmt(stmt_ *stmt.Stmt) { move_s_rici_stmt := stmt_.MoveSRiciStmt() op_code := instruction.OR suffix := this.ConvertSuffix(move_s_rici_stmt.Suffix(), instruction.RRICI) dc := this.ConvertPairReg(move_s_rici_stmt.Dc()) zero_reg := new(reg_descriptor.SpRegDescriptor) *zero_reg = reg_descriptor.ZERO ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(zero_reg) imm := this.EvaluateProgramCounter(move_s_rici_stmt.Imm()) condition := this.ConvertCondition(move_s_rici_stmt.Condition()) pc := this.EvaluateProgramCounter(move_s_rici_stmt.Pc()) instruction_ := new(instruction.Instruction) instruction_.InitSRrici(op_code, suffix, dc, ra, imm, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkMoveSRiStmt(stmt_ *stmt.Stmt) { move_s_ri_stmt := stmt_.MoveSRiStmt() // NOTE(bongjoon.hyun@gmail.com): move.s is implemented by using and.s:rki op_code := instruction.AND suffix := this.ConvertSuffix(move_s_ri_stmt.Suffix(), instruction.RRI) dc := this.ConvertPairReg(move_s_ri_stmt.Dc()) lneg_reg := new(reg_descriptor.SpRegDescriptor) *lneg_reg = reg_descriptor.LNEG ra := new(reg_descriptor.SrcRegDescriptor) ra.InitSpRegDescriptor(lneg_reg) imm := this.EvaluateProgramCounter(move_s_ri_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitSRri(op_code, suffix, dc, ra, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbIdRiiStmt(stmt_ *stmt.Stmt) { sb_id_rii_stmt := stmt_.SbIdRiiStmt() op_code := this.ConvertStoreOpCode(sb_id_rii_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_id_rii_stmt.Ra()) off := this.EvaluateProgramCounter(sb_id_rii_stmt.Off()) imm := this.EvaluateProgramCounter(sb_id_rii_stmt.Imm()) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbIdRiStmt(stmt_ *stmt.Stmt) { sb_id_ri_stmt := stmt_.SbIdRiStmt() op_code := this.ConvertStoreOpCode(sb_id_ri_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_id_ri_stmt.Ra()) off := this.EvaluateProgramCounter(sb_id_ri_stmt.Off()) imm := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitErii(op_code, endian, ra, off, imm) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSbRirStmt(stmt_ *stmt.Stmt) { sb_rir_stmt := stmt_.SbRirStmt() op_code := this.ConvertStoreOpCode(sb_rir_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_rir_stmt.Ra()) off := this.EvaluateProgramCounter(sb_rir_stmt.Off()) rb := this.ConvertSrcReg(sb_rir_stmt.Rb()) instruction_ := new(instruction.Instruction) instruction_.InitErir(op_code, endian, ra, off, rb) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkSdRidStmt(stmt_ *stmt.Stmt) { sb_rid_stmt := stmt_.SdRidStmt() op_code := this.ConvertStoreOpCode(sb_rid_stmt.OpCode()) endian := instruction.LITTLE ra := this.ConvertSrcReg(sb_rid_stmt.Ra()) off := this.EvaluateProgramCounter(sb_rid_stmt.Off()) db := this.ConvertPairReg(sb_rid_stmt.Db()) instruction_ := new(instruction.Instruction) instruction_.InitErid(op_code, endian, ra, off, db) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkStopStmt(stmt_ *stmt.Stmt) { op_code := instruction.STOP condition := cc.FALSE pc := int64(0) instruction_ := new(instruction.Instruction) instruction_.InitCi(op_code, condition, pc) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkTimeCfgRStmt(stmt_ *stmt.Stmt) { time_cfg_r_stmt := stmt_.TimeCfgRStmt() op_code := instruction.TIME_CFG ra := this.ConvertSrcReg(time_cfg_r_stmt.Ra()) instruction_ := new(instruction.Instruction) instruction_.InitZr(op_code, ra) cur_label := this.executable.CurSection().CurLabel() cur_label.Append(instruction_) } func (this *InstructionAssigner) WalkLabelStmt(stmt_ *stmt.Stmt) { label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() label_name := token.Attribute() if label_name != "__sys_used_mram_end" { this.executable.CurSection().CheckoutLabel(label_name) } } func (this *InstructionAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *InstructionAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } func (this *InstructionAssigner) ConvertCiOpCode(op_code *expr.Expr) instruction.OpCode { ci_op_code_expr := op_code.CiOpCodeExpr() token_type := ci_op_code_expr.Token().TokenType() if token_type == lexer.STOP { return instruction.STOP } else { err := errors.New("CI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDdciOpCode(op_code *expr.Expr) instruction.OpCode { ddci_op_code_expr := op_code.DdciOpCodeExpr() token_type := ddci_op_code_expr.Token().TokenType() if token_type == lexer.MOVD { return instruction.MOVD } else if token_type == lexer.SWAPD { return instruction.SWAPD } else { err := errors.New("DDCI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDmaRriOpCode(op_code *expr.Expr) instruction.OpCode { dma_rri_op_code_expr := op_code.DmaRriOpCodeExpr() token_type := dma_rri_op_code_expr.Token().TokenType() if token_type == lexer.LDMA { return instruction.LDMA } else if token_type == lexer.LDMAI { return instruction.LDMAI } else if token_type == lexer.SDMA { return instruction.SDMA } else { err := errors.New("DMA_RRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertDrdiciOpCode(op_code *expr.Expr) instruction.OpCode { drdici_op_code_expr := op_code.DrdiciOpCodeExpr() token_type := drdici_op_code_expr.Token().TokenType() if token_type == lexer.DIV_STEP { return instruction.DIV_STEP } else if token_type == lexer.MUL_STEP { return instruction.MUL_STEP } else { err := errors.New("DRDICI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertIOpCode(op_code *expr.Expr) instruction.OpCode { i_op_code_expr := op_code.IOpCodeExpr() token_type := i_op_code_expr.Token().TokenType() if token_type == lexer.FAULT { return instruction.FAULT } else { err := errors.New("I op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRiciOpCode(op_code *expr.Expr) instruction.OpCode { rici_op_code_expr := op_code.RiciOpCodeExpr() token_type := rici_op_code_expr.Token().TokenType() if token_type == lexer.ACQUIRE { return instruction.ACQUIRE } else if token_type == lexer.RELEASE { return instruction.RELEASE } else if token_type == lexer.BOOT { return instruction.BOOT } else if token_type == lexer.RESUME { return instruction.RESUME } else { err := errors.New("I op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertROpCode(op_code *expr.Expr) instruction.OpCode { r_op_code_expr := op_code.ROpCodeExpr() token_type := r_op_code_expr.Token().TokenType() if token_type == lexer.TIME { return instruction.TIME } else if token_type == lexer.NOP { return instruction.NOP } else { err := errors.New("R op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRrOpCode(op_code *expr.Expr) instruction.OpCode { rr_op_code_expr := op_code.RrOpCodeExpr() token_type := rr_op_code_expr.Token().TokenType() if token_type == lexer.CAO { return instruction.CAO } else if token_type == lexer.CLO { return instruction.CLO } else if token_type == lexer.CLS { return instruction.CLS } else if token_type == lexer.CLZ { return instruction.CLZ } else if token_type == lexer.EXTSB { return instruction.EXTSB } else if token_type == lexer.EXTSH { return instruction.EXTSH } else if token_type == lexer.EXTUB { return instruction.EXTUB } else if token_type == lexer.EXTUH { return instruction.EXTUH } else if token_type == lexer.SATS { return instruction.SATS } else if token_type == lexer.TIME_CFG { return instruction.TIME_CFG } else if token_type == lexer.MOVE { return instruction.OR } else if token_type == lexer.NEG { return instruction.SUB } else if token_type == lexer.NOT { return instruction.XOR } else { err := errors.New("RR op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRriOpCode(op_code *expr.Expr) instruction.OpCode { rri_op_code_expr := op_code.RriOpCodeExpr() token_type := rri_op_code_expr.Token().TokenType() if token_type == lexer.ADD { return instruction.ADD } else if token_type == lexer.ADDC { return instruction.ADDC } else if token_type == lexer.AND { return instruction.AND } else if token_type == lexer.ANDN { return instruction.ANDN } else if token_type == lexer.ASR { return instruction.ASR } else if token_type == lexer.CMPB4 { return instruction.CMPB4 } else if token_type == lexer.LSL { return instruction.LSL } else if token_type == lexer.LSL1 { return instruction.LSL1 } else if token_type == lexer.LSL1X { return instruction.LSL1X } else if token_type == lexer.LSLX { return instruction.LSLX } else if token_type == lexer.LSR { return instruction.LSR } else if token_type == lexer.LSR1 { return instruction.LSR1 } else if token_type == lexer.LSR1X { return instruction.LSR1X } else if token_type == lexer.LSRX { return instruction.LSRX } else if token_type == lexer.MUL_SH_SH { return instruction.MUL_SH_SH } else if token_type == lexer.MUL_SH_SL { return instruction.MUL_SH_SL } else if token_type == lexer.MUL_SH_UH { return instruction.MUL_SH_UH } else if token_type == lexer.MUL_SH_UL { return instruction.MUL_SH_UL } else if token_type == lexer.MUL_SL_SH { return instruction.MUL_SL_SH } else if token_type == lexer.MUL_SL_SL { return instruction.MUL_SL_SL } else if token_type == lexer.MUL_SL_UH { return instruction.MUL_SL_UH } else if token_type == lexer.MUL_SL_UL { return instruction.MUL_SL_UL } else if token_type == lexer.MUL_UH_UH { return instruction.MUL_UH_UH } else if token_type == lexer.MUL_UH_UL { return instruction.MUL_UH_UL } else if token_type == lexer.MUL_UL_UH { return instruction.MUL_UL_UH } else if token_type == lexer.MUL_UL_UL { return instruction.MUL_UL_UL } else if token_type == lexer.NAND { return instruction.NAND } else if token_type == lexer.NOR { return instruction.NOR } else if token_type == lexer.NXOR { return instruction.NXOR } else if token_type == lexer.OR { return instruction.OR } else if token_type == lexer.ORN { return instruction.ORN } else if token_type == lexer.ROL { return instruction.ROL } else if token_type == lexer.ROR { return instruction.ROR } else if token_type == lexer.RSUB { return instruction.RSUB } else if token_type == lexer.RSUBC { return instruction.RSUBC } else if token_type == lexer.SUB { return instruction.SUB } else if token_type == lexer.SUBC { return instruction.SUBC } else if token_type == lexer.XOR { return instruction.XOR } else if token_type == lexer.CALL { return instruction.CALL } else if token_type == lexer.HASH { return instruction.HASH } else { err := errors.New("RRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertRrriOpCode(op_code *expr.Expr) instruction.OpCode { rrri_op_code_expr := op_code.RrriOpCodeExpr() token_type := rrri_op_code_expr.Token().TokenType() if token_type == lexer.LSL_ADD { return instruction.LSL_ADD } else if token_type == lexer.LSL_SUB { return instruction.LSL_SUB } else if token_type == lexer.LSR_ADD { return instruction.LSR_ADD } else if token_type == lexer.ROL_ADD { return instruction.ROL_ADD } else { err := errors.New("RRRI op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertLoadOpCode(op_code *expr.Expr) instruction.OpCode { load_op_code_expr := op_code.LoadOpCodeExpr() token_type := load_op_code_expr.Token().TokenType() if token_type == lexer.LBS { return instruction.LBS } else if token_type == lexer.LBU { return instruction.LBU } else if token_type == lexer.LD { return instruction.LD } else if token_type == lexer.LHS { return instruction.LHS } else if token_type == lexer.LHU { return instruction.LHU } else if token_type == lexer.LW { return instruction.LW } else { err := errors.New("load op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertStoreOpCode(op_code *expr.Expr) instruction.OpCode { store_op_code_expr := op_code.StoreOpCodeExpr() token_type := store_op_code_expr.Token().TokenType() if token_type == lexer.SB { return instruction.SB } else if token_type == lexer.SB_ID { return instruction.SB_ID } else if token_type == lexer.SD { return instruction.SD } else if token_type == lexer.SD_ID { return instruction.SD_ID } else if token_type == lexer.SH { return instruction.SH } else if token_type == lexer.SH_ID { return instruction.SH_ID } else if token_type == lexer.SW { return instruction.SW } else if token_type == lexer.SW_ID { return instruction.SW_ID } else { err := errors.New("store op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertJumpOpCode(op_code *expr.Expr) instruction.OpCode { jump_op_code_expr := op_code.JumpOpCodeExpr() token_type := jump_op_code_expr.Token().TokenType() if token_type == lexer.JEQ { return instruction.SUB } else if token_type == lexer.JGES { return instruction.SUB } else if token_type == lexer.JGEU { return instruction.SUB } else if token_type == lexer.JGTS { return instruction.SUB } else if token_type == lexer.JGTU { return instruction.SUB } else if token_type == lexer.JLES { return instruction.SUB } else if token_type == lexer.JLEU { return instruction.SUB } else if token_type == lexer.JLTS { return instruction.SUB } else if token_type == lexer.JLTU { return instruction.SUB } else if token_type == lexer.JNEQ { return instruction.SUB } else if token_type == lexer.JNZ { return instruction.SUB } else if token_type == lexer.JUMP { return instruction.CALL } else if token_type == lexer.JZ { return instruction.SUB } else { err := errors.New("jump op code is not valid") panic(err) } } func (this *InstructionAssigner) ConvertSuffix( suffix *expr.Expr, base instruction.Suffix, ) instruction.Suffix { suffix_expr := suffix.SuffixExpr() token_type := suffix_expr.Token().TokenType() if token_type == lexer.S { if base == instruction.ERRI { return instruction.S_ERRI } else if base == instruction.RCI { return instruction.S_RCI } else if base == instruction.RIRCI { return instruction.S_RIRCI } else if base == instruction.RIRC { return instruction.S_RIRC } else if base == instruction.RRCI { return instruction.S_RRCI } else if base == instruction.RRC { return instruction.S_RRC } else if base == instruction.RRICI { return instruction.S_RRICI } else if base == instruction.RRIC { return instruction.S_RRIC } else if base == instruction.RRI { return instruction.S_RRI } else if base == instruction.RRRCI { return instruction.S_RRRCI } else if base == instruction.RRRC { return instruction.S_RRRC } else if base == instruction.RRRICI { return instruction.S_RRRICI } else if base == instruction.RRRI { return instruction.S_RRRI } else if base == instruction.RRR { return instruction.S_RRR } else if base == instruction.RR { return instruction.S_RR } else if base == instruction.R { return instruction.S_R } else { err := errors.New("base is not valid") panic(err) } } else if token_type == lexer.U { if base == instruction.ERRI { return instruction.U_ERRI } else if base == instruction.RCI { return instruction.U_RCI } else if base == instruction.RIRCI { return instruction.U_RIRCI } else if base == instruction.RIRC { return instruction.U_RIRC } else if base == instruction.RRCI { return instruction.U_RRCI } else if base == instruction.RRC { return instruction.U_RRC } else if base == instruction.RRICI { return instruction.U_RRICI } else if base == instruction.RRIC { return instruction.U_RRIC } else if base == instruction.RRI { return instruction.U_RRI } else if base == instruction.RRRCI { return instruction.U_RRRCI } else if base == instruction.RRRC { return instruction.U_RRRC } else if base == instruction.RRRICI { return instruction.U_RRRICI } else if base == instruction.RRRI { return instruction.U_RRRI } else if base == instruction.RRR { return instruction.U_RRR } else if base == instruction.RR { return instruction.U_RR } else if base == instruction.R { return instruction.U_R } else { err := errors.New("base is not valid") panic(err) } } else { err := errors.New("suffix is not valid") panic(err) } } func (this *InstructionAssigner) ConvertGpReg(expr_ *expr.Expr) *reg_descriptor.GpRegDescriptor { src_reg_expr := expr_.SrcRegExpr() index, err := strconv.Atoi(src_reg_expr.Token().Attribute()[1:]) if err != nil { panic(err) } gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(index) return gp_reg_descriptor } func (this *InstructionAssigner) ConvertSrcReg(expr_ *expr.Expr) *reg_descriptor.SrcRegDescriptor { src_reg_expr := expr_.SrcRegExpr() token := src_reg_expr.Token() token_type := token.TokenType() if token_type == lexer.GP_REG { gp_reg_descriptor := this.ConvertGpReg(expr_) src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitGpRegDescriptor(gp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ZERO_REG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ZERO src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ONE { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ONE src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID2 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID2 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID4 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID4 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.ID8 { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.ID8 src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.LNEG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.LNEG src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else if token_type == lexer.MNEG { sp_reg_descriptor := new(reg_descriptor.SpRegDescriptor) *sp_reg_descriptor = reg_descriptor.MNEG src_reg_descriptor := new(reg_descriptor.SrcRegDescriptor) src_reg_descriptor.InitSpRegDescriptor(sp_reg_descriptor) return src_reg_descriptor } else { err := errors.New("src reg is not valid") panic(err) } } func (this *InstructionAssigner) ConvertPairReg( token *lexer.Token, ) *reg_descriptor.PairRegDescriptor { index, err := strconv.Atoi(token.Attribute()[1:]) if err != nil { panic(err) } pair_reg_descriptor := new(reg_descriptor.PairRegDescriptor) pair_reg_descriptor.Init(index) return pair_reg_descriptor } func (this *InstructionAssigner) ConvertCondition(expr_ *expr.Expr) cc.Condition { condition_expr := expr_.ConditionExpr() token := condition_expr.Token() token_type := token.TokenType() if token_type == lexer.TRUE { return cc.TRUE } else if token_type == lexer.FALSE { return cc.FALSE } else if token_type == lexer.Z { return cc.Z } else if token_type == lexer.NZ { return cc.NZ } else if token_type == lexer.E { return cc.E } else if token_type == lexer.O { return cc.O } else if token_type == lexer.PL { return cc.PL } else if token_type == lexer.MI { return cc.MI } else if token_type == lexer.OV { return cc.OV } else if token_type == lexer.NOV { return cc.NOV } else if token_type == lexer.C { return cc.C } else if token_type == lexer.NC { return cc.NC } else if token_type == lexer.SZ { return cc.SZ } else if token_type == lexer.SNZ { return cc.SNZ } else if token_type == lexer.SPL { return cc.SPL } else if token_type == lexer.SMI { return cc.SMI } else if token_type == lexer.SO { return cc.SO } else if token_type == lexer.SE { return cc.SE } else if token_type == lexer.NC5 { return cc.NC5 } else if token_type == lexer.NC6 { return cc.NC6 } else if token_type == lexer.NC7 { return cc.NC7 } else if token_type == lexer.NC8 { return cc.NC8 } else if token_type == lexer.NC9 { return cc.NC9 } else if token_type == lexer.NC10 { return cc.NC10 } else if token_type == lexer.NC11 { return cc.NC11 } else if token_type == lexer.NC12 { return cc.NC12 } else if token_type == lexer.NC13 { return cc.NC13 } else if token_type == lexer.NC14 { return cc.NC14 } else if token_type == lexer.MAX { return cc.MAX } else if token_type == lexer.NMAX { return cc.NMAX } else if token_type == lexer.SH32 { return cc.SH32 } else if token_type == lexer.NSH32 { return cc.NSH32 } else if token_type == lexer.EQ { return cc.EQ } else if token_type == lexer.NEQ { return cc.NEQ } else if token_type == lexer.LTU { return cc.LTU } else if token_type == lexer.LEU { return cc.LEU } else if token_type == lexer.GTU { return cc.GTU } else if token_type == lexer.GEU { return cc.GEU } else if token_type == lexer.LTS { return cc.LTS } else if token_type == lexer.LES { return cc.LES } else if token_type == lexer.GTS { return cc.GTS } else if token_type == lexer.GES { return cc.GES } else if token_type == lexer.XZ { return cc.XZ } else if token_type == lexer.XNZ { return cc.XNZ } else if token_type == lexer.XLEU { return cc.XLEU } else if token_type == lexer.XGTU { return cc.XGTU } else if token_type == lexer.XLES { return cc.XLES } else if token_type == lexer.XGTS { return cc.XGTS } else if token_type == lexer.SMALL { return cc.SMALL } else if token_type == lexer.LARGE { return cc.LARGE } else { err := errors.New("condition is not valid") panic(err) } } func (this *InstructionAssigner) ConvertEndian(expr_ *expr.Expr) instruction.Endian { endian_expr := expr_.EndianExpr() token := endian_expr.Token() token_type := token.TokenType() if token_type == lexer.LITTLE { return instruction.LITTLE } else if token_type == lexer.BIG { return instruction.BIG } else { err := errors.New("endian is not valid") panic(err) } } func (this *InstructionAssigner) ConvertJumpCondition(op_code *expr.Expr) cc.Condition { jump_op_code_expr := op_code.JumpOpCodeExpr() token_type := jump_op_code_expr.Token().TokenType() if token_type == lexer.JEQ { return cc.Z } else if token_type == lexer.JGES { return cc.GES } else if token_type == lexer.JGEU { return cc.GEU } else if token_type == lexer.JGTS { return cc.GTS } else if token_type == lexer.JGTU { return cc.GTU } else if token_type == lexer.JLES { return cc.LES } else if token_type == lexer.JLEU { return cc.LEU } else if token_type == lexer.JLTS { return cc.LTS } else if token_type == lexer.JLTU { return cc.LTU } else if token_type == lexer.JNEQ { return cc.NZ } else if token_type == lexer.JNZ { return cc.NZ } else if token_type == lexer.JZ { return cc.Z } else { err := errors.New("jump op code is not valid") panic(err) } } func (this *InstructionAssigner) EvaluateProgramCounter(expr_ *expr.Expr) int64 { program_counter_expr := expr_.ProgramCounterExpr() child_expr := program_counter_expr.Expr() child_expr_type := child_expr.ExprType() if child_expr_type == expr.PRIMARY { return this.EvaluatePrimary(child_expr) } else if child_expr_type == expr.NEGATIVE_NUMBER { return this.EvaluateNegativeNumber(child_expr) } else if child_expr_type == expr.BINARY_ADD { return this.EvaluateBinaryAdd(child_expr) } else if child_expr_type == expr.BINARY_SUB { return this.EvaluateBinarySub(child_expr) } else { err := errors.New("program counter expr is not valid") panic(err) } } func (this *InstructionAssigner) EvaluatePrimary(expr_ *expr.Expr) int64 { primary_expr := expr_.PrimaryExpr() token := primary_expr.Token() token_type := token.TokenType() if token_type == lexer.POSITIVIE_NUMBER { return this.EvaluatePositiveNumber(token) } else if token_type == lexer.HEX_NUMBER { return this.EvaluateHexNumber(token) } else if token_type == lexer.IDENTIFIER { return this.EvaluateIdentifier(token) } else { err := errors.New("primary expr is not valid") panic(err) } } func (this *InstructionAssigner) EvaluatePositiveNumber(token *lexer.Token) int64 { value, err := strconv.ParseInt(token.Attribute(), 10, 64) if err != nil { panic(err) } return value } func (this *InstructionAssigner) EvaluateHexNumber(token *lexer.Token) int64 { attribute := token.Attribute() var value int64 var err error if attribute[:2] == "0x" { value, err = strconv.ParseInt(attribute[2:], 16, 64) } else { value, err = strconv.ParseInt(attribute, 16, 64) } if err != nil { panic(err) } return value } func (this *InstructionAssigner) EvaluateIdentifier(token *lexer.Token) int64 { name := token.Attribute() label := this.executable.Label(name) linker_constant := this.linker_script.LinkerConstant(name) if label != nil { if linker_constant != nil { err := errors.New("label and linker constant both exist") panic(err) } return label.Address() } else if linker_constant != nil { return linker_constant.Value() } else { err := errors.New("label and linker constant do not exist") panic(err) } } func (this *InstructionAssigner) EvaluateNegativeNumber(expr_ *expr.Expr) int64 { negative_number_expr := expr_.NegativeNumberExpr() return -this.EvaluatePositiveNumber(negative_number_expr.Token()) } func (this *InstructionAssigner) EvaluateBinaryAdd(expr_ *expr.Expr) int64 { binary_add_expr := expr_.BinaryAddExpr() is_operand1_nr_tasklets := binary_add_expr.Operand1(). PrimaryExpr(). Token(). Attribute() == "NR_TASKLETS" is_operand2_number := binary_add_expr.Operand2(). PrimaryExpr(). Token(). TokenType() != lexer.IDENTIFIER if !is_operand1_nr_tasklets && is_operand2_number { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) return this.EvaluatePrimary( binary_add_expr.Operand1(), ) + iram_data_size*this.EvaluatePrimary( binary_add_expr.Operand2(), ) } else { return this.EvaluatePrimary( binary_add_expr.Operand1(), ) + this.EvaluatePrimary( binary_add_expr.Operand2(), ) } } func (this *InstructionAssigner) EvaluateBinarySub(expr_ *expr.Expr) int64 { binary_sub_expr := expr_.BinarySubExpr() is_operand1_nr_tasklets := binary_sub_expr.Operand1(). PrimaryExpr(). Token(). Attribute() == "NR_TASKLETS" is_operand2_number := binary_sub_expr.Operand2(). PrimaryExpr(). Token(). TokenType() != lexer.IDENTIFIER if !is_operand1_nr_tasklets && is_operand2_number { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) return this.EvaluatePrimary( binary_sub_expr.Operand1(), ) - iram_data_size*this.EvaluatePrimary( binary_sub_expr.Operand2(), ) } else { return this.EvaluatePrimary( binary_sub_expr.Operand1(), ) - this.EvaluatePrimary( binary_sub_expr.Operand2(), ) } } func (this *InstructionAssigner) EvaluateSectionName(expr_ *expr.Expr) int64 { section_name := this.ConvertSectionName(expr_) name := "" return this.executable.Section(section_name, name).Address() } func (this *InstructionAssigner) IsZeroReg(expr_ *expr.Expr) bool { src_reg_expr := expr_.SrcRegExpr() return src_reg_expr.Token().TokenType() == lexer.ZERO_REG } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/label_assigner.go ================================================ package logic import ( "errors" "strconv" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" "uPIMulator/src/misc" ) type LabelAssigner struct { executable *kernel.Executable walker *parser.Walker } func (this *LabelAssigner) Init() { this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback(stmt.ASCII, this.WalkAsciiStmt) this.walker.RegisterStmtCallback(stmt.ASCIZ, this.WalkAscizStmt) this.walker.RegisterStmtCallback(stmt.BYTE, this.WalkByteStmt) this.walker.RegisterStmtCallback(stmt.LONG_PROGRAM_COUNTER, this.WalkLongProgramCounterStmt) this.walker.RegisterStmtCallback(stmt.LONG_SECTION_NAME, this.WalkLongSectionNameStmt) this.walker.RegisterStmtCallback(stmt.QUAD, this.WalkQuadStmt) this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.SHORT, this.WalkShortStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) this.walker.RegisterStmtCallback(stmt.ZERO_DOUBLE_NUMBER, this.WalkZeroDoubleNumberStmt) this.walker.RegisterStmtCallback(stmt.ZERO_SINGLE_NUMBER, this.WalkZeroSingleNumberStmt) this.walker.RegisterStmtCallback(stmt.CI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DDCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DMA_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DRDICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.EDRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERID, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.ERRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.I, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.NOP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRIC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RRR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_ERRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RIRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RIRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRIC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRCI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRC, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RRR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.S_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.BKP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.BOOT_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.CALL_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.CALL_RR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.DIV_STEP_DRDI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JEQ_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JNZ_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JUMP_I, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.JUMP_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LBS_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LBS_S_RRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LD_DRI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVD_DD, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RICI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.MOVE_S_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RII, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_ID_RI, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SB_RIR, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.SD_RID, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.STOP, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.TIME_CFG_R, this.WalkInstructionStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *LabelAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *LabelAssigner) WalkAsciiStmt(stmt_ *stmt.Stmt) { ascii_stmt := stmt_.AsciiStmt() token := ascii_stmt.Token() attribute := token.Attribute() // TODO(bongjoon.hyun@gmail.com): decode octal code cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + int64(len(attribute)) - 2) } func (this *LabelAssigner) WalkAscizStmt(stmt_ *stmt.Stmt) { asciz_stmt := stmt_.AscizStmt() token := asciz_stmt.Token() attribute := token.Attribute() cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + int64(len(attribute)) - 1) } func (this *LabelAssigner) WalkByteStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 1) } func (this *LabelAssigner) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 4) } func (this *LabelAssigner) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 4) } func (this *LabelAssigner) WalkQuadStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 8) } func (this *LabelAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) section_flags := this.ConvertSectionFlags(section_identifier_number_stmt.Token()) section_type := this.ConvertSectionType(section_identifier_number_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) section_flags := this.ConvertSectionFlags(section_identifier_stmt.Token()) section_type := this.ConvertSectionType(section_identifier_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_flags := this.ConvertSectionFlags(section_stack_sizes_stmt.Token()) section_type := this.ConvertSectionType(section_stack_sizes_stmt.Expr1()) section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" section_flags := this.ConvertSectionFlags(section_string_number_stmt.Token()) section_type := this.ConvertSectionType(section_string_number_stmt.Expr2()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" section_flags := this.ConvertSectionFlags(section_string_stmt.Token()) section_type := this.ConvertSectionType(section_string_stmt.Expr2()) if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkShortStmt(stmt_ *stmt.Stmt) { cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + 2) } func (this *LabelAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" section_flags := make(map[kernel.SectionFlag]bool) section_type := kernel.PROGBITS if this.executable.Section(section_name, name) == nil { this.executable.AddSection(section_name, name, section_flags, section_type) } this.executable.CheckoutSection(section_name, name) } func (this *LabelAssigner) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() program_counter_expr := zero_double_number_stmt.Expr1().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() attribute := token.Attribute() size, err := strconv.ParseInt(attribute, 10, 64) if err != nil { panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + size) } func (this *LabelAssigner) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() program_counter_expr := zero_single_number_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() attribute := token.Attribute() size, err := strconv.ParseInt(attribute, 10, 64) if err != nil { panic(err) } cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + size) } func (this *LabelAssigner) WalkInstructionStmt(stmt_ *stmt.Stmt) { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_width := config_loader.IramDataWidth() instruction_size := int64(iram_data_width / 8) cur_label := this.executable.CurSection().CurLabel() cur_label.SetSize(cur_label.Size() + instruction_size) } func (this *LabelAssigner) WalkLabelStmt(stmt_ *stmt.Stmt) { label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() label_name := token.Attribute() if label_name != "__sys_used_mram_end" { if this.executable.CurSection().Label(label_name) == nil { this.executable.CurSection().AppendLabel(label_name) } this.executable.CurSection().CheckoutLabel(label_name) } } func (this *LabelAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *LabelAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } func (this *LabelAssigner) ConvertSectionFlags(token *lexer.Token) map[kernel.SectionFlag]bool { attribute := token.Attribute() section_flags := make(map[kernel.SectionFlag]bool) for i := 1; i < len(attribute)-1; i++ { if attribute[i] == 'a' { section_flags[kernel.ALLOC] = true } else if attribute[i] == 'w' { section_flags[kernel.WRITE] = true } else if attribute[i] == 'x' { section_flags[kernel.EXECINSTR] = true } else if attribute[i] == 'o' { section_flags[kernel.LINK_ORDER] = true } else if attribute[i] == 'M' { section_flags[kernel.MERGE] = true } else if attribute[i] == 'S' { section_flags[kernel.STRINGS] = true } else { err := errors.New("section flag is not valid") panic(err) } } return section_flags } func (this *LabelAssigner) ConvertSectionType(expr_ *expr.Expr) kernel.SectionType { section_type_expr := expr_.SectionTypeExpr() token := section_type_expr.Token() token_type := token.TokenType() if token_type == lexer.PROGBITS { return kernel.PROGBITS } else if token_type == lexer.NOBITS { return kernel.NOBITS } else { err := errors.New("section type is not valid") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/linker_constant.go ================================================ package logic type LinkerConstant struct { name string value int64 } func (this *LinkerConstant) Init(name string) { this.name = name this.value = 0 } func (this *LinkerConstant) Name() string { return this.name } func (this *LinkerConstant) Value() int64 { return this.value } func (this *LinkerConstant) SetValue(value int64) { this.value = value } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/linker_script.go ================================================ package logic import ( "errors" "fmt" "math" "strconv" "strings" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/misc" ) type LinkerScript struct { command_line_parser *misc.CommandLineParser num_tasklets int min_access_granularity int64 linker_constants map[string]*LinkerConstant } func (this *LinkerScript) Init(command_line_parser *misc.CommandLineParser) { this.command_line_parser = command_line_parser this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.linker_constants = make(map[string]*LinkerConstant) this.InitLinkerConstants() } func (this *LinkerScript) Assign(executable *kernel.Executable) { this.AssignAtomic(executable) this.AssignIram(executable) this.AssignWram(executable) this.AssignMram(executable) } func (this *LinkerScript) HasLinkerConstant(name string) bool { _, found := this.linker_constants[name] return found } func (this *LinkerScript) LinkerConstant(name string) *LinkerConstant { return this.linker_constants[name] } func (this *LinkerScript) InitLinkerConstants() { config_loader := new(misc.ConfigLoader) config_loader.Init() max_num_tasklets := config_loader.MaxNumTasklets() stack_size := config_loader.StackSize() this.linker_constants["NR_TASKLETS"] = new(LinkerConstant) this.linker_constants["NR_TASKLETS"].Init("NR_TASKLETS") this.linker_constants["NR_TASKLETS"].SetValue(int64(this.num_tasklets)) for i := 0; i < max_num_tasklets; i++ { stack_size_tasklet := "STACK_SIZE_TASKLET_" + strconv.Itoa(i) this.linker_constants[stack_size_tasklet] = new(LinkerConstant) this.linker_constants[stack_size_tasklet].Init(stack_size_tasklet) this.linker_constants[stack_size_tasklet].SetValue(stack_size) } this.linker_constants["__atomic_start_addr"] = new(LinkerConstant) this.linker_constants["__atomic_start_addr"].Init("__atomic_start_addr") this.linker_constants["__atomic_used_addr"] = new(LinkerConstant) this.linker_constants["__atomic_used_addr"].Init("__atomic_used_addr") this.linker_constants["__atomic_end_addr"] = new(LinkerConstant) this.linker_constants["__atomic_end_addr"].Init("__atomic_end_addr") this.linker_constants["__rodata_start_addr"] = new(LinkerConstant) this.linker_constants["__rodata_start_addr"].Init("__rodata_start_addr") this.linker_constants["__rodata_end_addr"] = new(LinkerConstant) this.linker_constants["__rodata_end_addr"].Init("__rodata_end_addr") for i := 0; i < max_num_tasklets; i++ { sys_stack_thread := "__sys_stack_thread_" + strconv.Itoa(i) this.linker_constants[sys_stack_thread] = new(LinkerConstant) this.linker_constants[sys_stack_thread].Init(sys_stack_thread) } this.linker_constants["__sw_cache_buffer"] = new(LinkerConstant) this.linker_constants["__sw_cache_buffer"].Init("__sw_cache_buffer") this.linker_constants["__sys_heap_pointer_reset"] = new(LinkerConstant) this.linker_constants["__sys_heap_pointer_reset"].Init("__sys_heap_pointer_reset") this.linker_constants["__sys_used_mram_end"] = new(LinkerConstant) this.linker_constants["__sys_used_mram_end"].Init("__sys_used_mram_end") } func (this *LinkerScript) AssignAtomic(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.AtomicOffset() this.linker_constants["__atomic_start_addr"].SetValue(cur_address) this.linker_constants["__atomic_used_addr"].SetValue(cur_address) for section, _ := range executable.Sections(kernel.ATOMIC) { section.SetAddress(cur_address) cur_address += section.Size() } this.linker_constants["__atomic_end_addr"].SetValue(cur_address) if cur_address >= config_loader.AtomicOffset()+config_loader.AtomicSize() { err := errors.New("address is larger than the atomic end address") panic(err) } } func (this *LinkerScript) AssignIram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.IramOffset() bootstrap := executable.Section(kernel.TEXT, "__bootstrap") if bootstrap == nil { err := errors.New("bootstrap is not found") panic(err) } bootstrap.SetAddress(cur_address) cur_address += bootstrap.Size() text_default := executable.Section(kernel.TEXT, "") if text_default != nil { text_default.SetAddress(cur_address) cur_address += text_default.Size() } for section, _ := range executable.Sections(kernel.TEXT) { if section.Name() != "__bootstrap" && section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } if cur_address >= config_loader.IramOffset()+config_loader.IramSize() { err := errors.New("address is larger than the IRAM end address") panic(err) } } func (this *LinkerScript) AssignWram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.WramOffset() sys_zero := executable.Section(kernel.DATA, "__sys_zero") if sys_zero != nil { sys_zero.SetAddress(cur_address) cur_address += sys_zero.Size() } immediate_memory := executable.Section(kernel.DATA, "immediate_memory") if immediate_memory != nil { immediate_memory.SetAddress(cur_address) cur_address += immediate_memory.Size() } for section, _ := range executable.Sections(kernel.DATA) { if strings.Contains(section.Name(), "immediate_memory.") { section.SetAddress(cur_address) cur_address += section.Size() } } this.linker_constants["__rodata_start_addr"].SetValue(cur_address) rodata_default := executable.Section(kernel.RODATA, "") if rodata_default != nil { rodata_default.SetAddress(cur_address) cur_address += rodata_default.Size() } for section, _ := range executable.Sections(kernel.RODATA) { if section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } this.linker_constants["__rodata_end_addr"].SetValue(cur_address) bss_default := executable.Section(kernel.BSS, "") if bss_default != nil { bss_default.SetAddress(cur_address) cur_address += bss_default.Size() } for section, _ := range executable.Sections(kernel.BSS) { if section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } sys_keep := executable.Section(kernel.DATA, "__sys_keep") if sys_keep != nil { sys_keep.SetAddress(cur_address) cur_address += sys_keep.Size() } data_default := executable.Section(kernel.DATA, "") if data_default != nil { data_default.SetAddress(cur_address) cur_address += data_default.Size() } for section, _ := range executable.Sections(kernel.DATA) { if section.Name() != "__sys_zero" && section.Name() != "__sys_keep" && !strings.Contains(section.Name(), "immediate_memory") && section.Name() != "" { section.SetAddress(cur_address) cur_address += section.Size() } } // TODO(bongjoon.hyun@gmail.com): figure out ".data.__sys_host" section dpu_host := executable.Section(kernel.DPU_HOST, "") if dpu_host != nil { dpu_host.SetAddress(cur_address) cur_address += dpu_host.Size() } // TODO(bongjoon.hyun@gmail.com): figure out ".data.__sys_profilng" section // TODO(bongjoon.hyun@gmail.com): figure out ".data.stacks" section for i := 0; i < config_loader.MaxNumTasklets(); i++ { sys_stack_thread := "__sys_stack_thread_" + strconv.Itoa(i) this.linker_constants[sys_stack_thread].SetValue(cur_address) stack_size_tasklet := "STACK_SIZE_TASKLET_" + strconv.Itoa(i) cur_address += this.linker_constants[stack_size_tasklet].Value() } // TODO(bongjoon.hyun@gmail.com): figure out ".data.sw_cache" section this.linker_constants["__sw_cache_buffer"].SetValue(cur_address) cur_address += int64(8 * config_loader.MaxNumTasklets()) // TODO(bongjoon.hyun@gmail.com): figure out ".data.heap_pointer_reset" section cur_address = int64( math.Ceil(float64(cur_address)/float64(this.min_access_granularity)), ) * int64( this.min_access_granularity, ) this.linker_constants["__sys_heap_pointer_reset"].SetValue(cur_address) if cur_address >= config_loader.WramOffset()+config_loader.WramSize() { err := errors.New("address is larger than the WRAM end address") panic(err) } } func (this *LinkerScript) AssignMram(executable *kernel.Executable) { config_loader := new(misc.ConfigLoader) config_loader.Init() cur_address := config_loader.MramOffset() for section, _ := range executable.Sections(kernel.DEBUG_ABBREV) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_FRAME) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_INFO) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_LINE) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_LOC) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_RANGES) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.DEBUG_STR) { section.SetAddress(cur_address) cur_address += section.Size() } for section, _ := range executable.Sections(kernel.STACK_SIZES) { section.SetAddress(cur_address) cur_address += section.Size() } noinit := executable.Section(kernel.MRAM, "noinit") if noinit != nil { noinit.SetAddress(cur_address) cur_address += noinit.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.") && !strings.Contains(section.Name(), "noinit.keep") { section.SetAddress(cur_address) cur_address += section.Size() } } noinit_keep := executable.Section(kernel.MRAM, "noinit.keep") if noinit_keep != nil { noinit_keep.SetAddress(cur_address) cur_address += noinit_keep.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.keep") && !strings.Contains(section.Name(), "noinit.keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "noinit.keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } mram_default := executable.Section(kernel.MRAM, "") if mram_default != nil { mram_default.SetAddress(cur_address) cur_address += mram_default.Size() } for section, _ := range executable.Sections(kernel.MRAM) { if section.Name() != "" && !strings.Contains(section.Name(), "noinit") && !strings.Contains(section.Name(), "keep") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "keep") && !strings.Contains(section.Name(), "keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } for section, _ := range executable.Sections(kernel.MRAM) { if strings.Contains(section.Name(), "keep.") { section.SetAddress(cur_address) cur_address += section.Size() } } cur_address = int64( math.Ceil(float64(cur_address)/float64(this.min_access_granularity)), ) * this.min_access_granularity this.linker_constants["__sys_used_mram_end"].SetValue(cur_address) if cur_address >= config_loader.MramOffset()+config_loader.MramSize() { err := errors.New("address is larger than the MRAM end address") panic(err) } } func (this *LinkerScript) DumpValues(path string) { lines := make([]string, 0) for _, linker_constant := range this.linker_constants { line := fmt.Sprintf("%s: %d", linker_constant.Name(), linker_constant.Value()) lines = append(lines, line) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/liveness_analyzer.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" ) type LivenessAnalyzer struct { liveness *kernel.Liveness walker *parser.Walker } func (this *LivenessAnalyzer) Init() { this.liveness = new(kernel.Liveness) this.liveness.Init() this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterExprCallback(expr.PRIMARY, this.WalkPrimaryExpr) this.walker.RegisterStmtCallback(stmt.GLOBAL, this.WalkGlobalStmt) this.walker.RegisterStmtCallback(stmt.SET, this.WalkSetStmt) this.walker.RegisterStmtCallback(stmt.LABEL, this.WalkLabelStmt) } func (this *LivenessAnalyzer) Analyze(relocatable *kernel.Relocatable) *kernel.Liveness { this.walker.Walk(relocatable.Ast()) return this.liveness } func (this *LivenessAnalyzer) WalkPrimaryExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PRIMARY { err := errors.New("expr type is not primary") panic(err) } primary_expr := expr_.PrimaryExpr() token := primary_expr.Token() if token.TokenType() == lexer.IDENTIFIER { this.liveness.AddUse(token.Attribute()) } } func (this *LivenessAnalyzer) WalkGlobalStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.GLOBAL { err := errors.New("stmt type is not global") panic(err) } global_stmt := stmt_.GlobalStmt() program_counter_expr := global_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute != "__sys_used_mram_end" { this.liveness.AddGlobalSymbol(attribute) } } func (this *LivenessAnalyzer) WalkSetStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SET { err := errors.New("stmt type is not set") panic(err) } set_stmt := stmt_.SetStmt() program_counter_expr1 := set_stmt.Expr1().ProgramCounterExpr() program_counter_expr2 := set_stmt.Expr2().ProgramCounterExpr() primary_expr1 := program_counter_expr1.Expr().PrimaryExpr() primary_expr2 := program_counter_expr2.Expr().PrimaryExpr() token1 := primary_expr1.Token() token2 := primary_expr2.Token() if token1.TokenType() != lexer.IDENTIFIER { err := errors.New("token1 type is not identifier") panic(err) } if token2.TokenType() != lexer.IDENTIFIER { err := errors.New("token2 type is not identifier") panic(err) } this.liveness.AddDef(token1.Attribute()) this.liveness.AddUse(token2.Attribute()) } func (this *LivenessAnalyzer) WalkLabelStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LABEL { err := errors.New("stmt type is not label") panic(err) } label_stmt := stmt_.LabelStmt() program_counter_expr := label_stmt.Expr().ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute != "__sys_used_mram_end" { this.liveness.AddDef(attribute) } } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/logic/set_assigner.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" ) type SetAssigner struct { executable *kernel.Executable walker *parser.Walker } func (this *SetAssigner) Init() { this.walker = new(parser.Walker) this.walker.Init() this.walker.RegisterStmtCallback( stmt.SECTION_IDENTIFIER_NUMBER, this.WalkSectionIdentifierNumberStmt, ) this.walker.RegisterStmtCallback(stmt.SECTION_IDENTIFIER, this.WalkSectionIdentifierStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STACK_SIZES, this.WalkSectionStackSizes) this.walker.RegisterStmtCallback(stmt.SECTION_STRING_NUMBER, this.WalkSectionStringNumberStmt) this.walker.RegisterStmtCallback(stmt.SECTION_STRING, this.WalkSectionStringStmt) this.walker.RegisterStmtCallback(stmt.TEXT, this.WalkTextStmt) } func (this *SetAssigner) Assign(executable *kernel.Executable) { this.executable = executable this.walker.Walk(executable.Ast()) } func (this *SetAssigner) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { section_identifier_number_stmt := stmt_.SectionIdentifierNumberStmt() section_name := this.ConvertSectionName(section_identifier_number_stmt.Expr1()) name := this.ConvertName(section_identifier_number_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { section_identifier_stmt := stmt_.SectionIdentifierStmt() section_name := this.ConvertSectionName(section_identifier_stmt.Expr1()) name := this.ConvertName(section_identifier_stmt.Expr2()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStackSizes(stmt_ *stmt.Stmt) { section_stack_sizes_stmt := stmt_.SectionStackSizesStmt() section_name := kernel.STACK_SIZES section_name_expr := section_stack_sizes_stmt.Expr2().SectionNameExpr() token := section_name_expr.Token() token_type := token.TokenType() name := "" if token_type == lexer.ATOMIC { name += ".atomic." } else if token_type == lexer.BSS { name += ".bss." } else if token_type == lexer.DATA { name += ".data." } else if token_type == lexer.DEBUG_ABBREV { name += ".debug_abbrev." } else if token_type == lexer.DEBUG_FRAME { name += ".debug_frame." } else if token_type == lexer.DEBUG_INFO { name += ".debug_info." } else if token_type == lexer.DEBUG_LINE { name += ".debug_line." } else if token_type == lexer.DEBUG_LOC { name += ".debug_loc." } else if token_type == lexer.DEBUG_RANGES { name += ".debug_ranges." } else if token_type == lexer.DEBUG_STR { name += ".debug_str." } else if token_type == lexer.DPU_HOST { name += ".dpu_host." } else if token_type == lexer.MRAM { name += ".mram." } else if token_type == lexer.RODATA { name += ".rodata." } else if token_type == lexer.STACK_SIZES { name += ".stack_sizes." } else if token_type == lexer.TEXT { name += ".text." } else { err := errors.New("section name is not valid") panic(err) } name += this.ConvertName(section_stack_sizes_stmt.Expr3()) this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { section_string_number_stmt := stmt_.SectionStringNumberStmt() section_name := this.ConvertSectionName(section_string_number_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSectionStringStmt(stmt_ *stmt.Stmt) { section_string_stmt := stmt_.SectionStringStmt() section_name := this.ConvertSectionName(section_string_stmt.Expr1()) name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) WalkSetStmt(stmt_ *stmt.Stmt) { set_stmt := stmt_.SetStmt() program_counter_expr1 := set_stmt.Expr1().ProgramCounterExpr() program_counter_expr2 := set_stmt.Expr2().ProgramCounterExpr() primary_expr1 := program_counter_expr1.Expr().PrimaryExpr() primary_expr2 := program_counter_expr2.Expr().PrimaryExpr() token1 := primary_expr1.Token() token2 := primary_expr2.Token() attribute1 := token1.Attribute() attribute2 := token2.Attribute() src_label := this.executable.CurSection().Label(attribute1) if this.executable.CurSection().Label(attribute2) == nil { this.executable.CurSection().AppendLabel(attribute2) } dst_label := this.executable.CurSection().Label(attribute2) dst_label.SetAddress(src_label.Address()) } func (this *SetAssigner) WalkTextStmt(stmt_ *stmt.Stmt) { section_name := kernel.TEXT name := "" this.executable.CheckoutSection(section_name, name) } func (this *SetAssigner) ConvertSectionName(expr_ *expr.Expr) kernel.SectionName { section_name_expr := expr_.SectionNameExpr() token_type := section_name_expr.Token().TokenType() if token_type == lexer.ATOMIC { return kernel.ATOMIC } else if token_type == lexer.BSS { return kernel.BSS } else if token_type == lexer.DATA { return kernel.DATA } else if token_type == lexer.DEBUG_ABBREV { return kernel.DEBUG_ABBREV } else if token_type == lexer.DEBUG_FRAME { return kernel.DEBUG_FRAME } else if token_type == lexer.DEBUG_INFO { return kernel.DEBUG_INFO } else if token_type == lexer.DEBUG_LINE { return kernel.DEBUG_LINE } else if token_type == lexer.DEBUG_LOC { return kernel.DEBUG_LOC } else if token_type == lexer.DEBUG_RANGES { return kernel.DEBUG_RANGES } else if token_type == lexer.DEBUG_STR { return kernel.DEBUG_STR } else if token_type == lexer.DPU_HOST { return kernel.DPU_HOST } else if token_type == lexer.MRAM { return kernel.MRAM } else if token_type == lexer.RODATA { return kernel.RODATA } else if token_type == lexer.STACK_SIZES { return kernel.STACK_SIZES } else if token_type == lexer.TEXT { return kernel.TEXT } else { err := errors.New("section name is not valid") panic(err) } } func (this *SetAssigner) ConvertName(expr_ *expr.Expr) string { program_counter_expr := expr_.ProgramCounterExpr() primary_expr := program_counter_expr.Expr().PrimaryExpr() token := primary_expr.Token() if token.TokenType() != lexer.IDENTIFIER { err := errors.New("token type is not identifier") panic(err) } attribute := token.Attribute() if attribute[0] != '.' { err := errors.New("attribute does not start with .") panic(err) } return attribute[1:] } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parse_job.go ================================================ package linker import ( "fmt" "uPIMulator/src/device/linker/kernel" "uPIMulator/src/device/linker/parser" ) type ParseJob struct { relocatable *kernel.Relocatable } func (this *ParseJob) Init(relocatable *kernel.Relocatable) { this.relocatable = relocatable } func (this *ParseJob) Execute() { fmt.Printf("Parsing %s...\n", this.relocatable.Path()) parser_ := new(parser.Parser) parser_.Init() ast := parser_.Parse(this.relocatable.TokenStream()) this.relocatable.SetAst(ast) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/ast.go ================================================ package parser import ( "uPIMulator/src/device/linker/parser/stmt" ) type Ast struct { stmts []*stmt.Stmt } func (this *Ast) Init(stmts []*stmt.Stmt) { this.stmts = stmts } func (this *Ast) Length() int { return len(this.stmts) } func (this *Ast) Get(pos int) *stmt.Stmt { return this.stmts[pos] } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/binary_add_expr.go ================================================ package expr import ( "errors" ) type BinaryAddExpr struct { operand1 *Expr operand2 *Expr } func (this *BinaryAddExpr) Init(operand1 *Expr, operand2 *Expr) { if operand1.ExprType() != PRIMARY { err := errors.New("operand1 is not a primary expr") panic(err) } if operand2.ExprType() != PRIMARY { err := errors.New("operand2 is not a primary expr") panic(err) } this.operand1 = operand1 this.operand2 = operand2 } func (this *BinaryAddExpr) Operand1() *Expr { return this.operand1 } func (this *BinaryAddExpr) Operand2() *Expr { return this.operand2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/binary_sub_expr.go ================================================ package expr import ( "errors" ) type BinarySubExpr struct { operand1 *Expr operand2 *Expr } func (this *BinarySubExpr) Init(operand1 *Expr, operand2 *Expr) { if operand1.ExprType() != PRIMARY { err := errors.New("operand1 is not a primary expr") panic(err) } if operand2.ExprType() != PRIMARY { err := errors.New("operand2 is not a primary expr") panic(err) } this.operand1 = operand1 this.operand2 = operand2 } func (this *BinarySubExpr) Operand1() *Expr { return this.operand1 } func (this *BinarySubExpr) Operand2() *Expr { return this.operand2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/ci_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type CiOpCodeExpr struct { token *lexer.Token } func (this *CiOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.STOP { err := errors.New("token type is not a CI op code") panic(err) } this.token = token } func (this *CiOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/condition_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type ConditionExpr struct { token *lexer.Token } func (this *ConditionExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.TRUE && token_type != lexer.FALSE && token_type != lexer.Z && token_type != lexer.NZ && token_type != lexer.E && token_type != lexer.O && token_type != lexer.PL && token_type != lexer.MI && token_type != lexer.OV && token_type != lexer.NOV && token_type != lexer.C && token_type != lexer.NC && token_type != lexer.SZ && token_type != lexer.SNZ && token_type != lexer.SPL && token_type != lexer.SMI && token_type != lexer.SO && token_type != lexer.SE && token_type != lexer.NC5 && token_type != lexer.NC6 && token_type != lexer.NC7 && token_type != lexer.NC8 && token_type != lexer.NC9 && token_type != lexer.NC10 && token_type != lexer.NC11 && token_type != lexer.NC12 && token_type != lexer.NC13 && token_type != lexer.NC14 && token_type != lexer.MAX && token_type != lexer.NMAX && token_type != lexer.SH32 && token_type != lexer.NSH32 && token_type != lexer.EQ && token_type != lexer.NEQ && token_type != lexer.LTU && token_type != lexer.LEU && token_type != lexer.GTU && token_type != lexer.GEU && token_type != lexer.LTS && token_type != lexer.LES && token_type != lexer.GTS && token_type != lexer.GES && token_type != lexer.XZ && token_type != lexer.XNZ && token_type != lexer.XLEU && token_type != lexer.XGTU && token_type != lexer.XLES && token_type != lexer.XGTS && token_type != lexer.SMALL && token_type != lexer.LARGE { err := errors.New("token type is not a condition") panic(err) } this.token = token } func (this *ConditionExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/ddci_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type DdciOpCodeExpr struct { token *lexer.Token } func (this *DdciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.MOVD && token_type != lexer.SWAPD { err := errors.New("token type is not a DDCI op code") panic(err) } this.token = token } func (this *DdciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/dma_rri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type DmaRriOpCodeExpr struct { token *lexer.Token } func (this *DmaRriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LDMA && token_type != lexer.LDMAI && token_type != lexer.SDMA { err := errors.New("token type is not a DMA_RRI op code") panic(err) } this.token = token } func (this *DmaRriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/drdici_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type DrdiciOpCodeExpr struct { token *lexer.Token } func (this *DrdiciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.DIV_STEP && token_type != lexer.MUL_STEP { err := errors.New("token type is not a DRDICI op code") panic(err) } this.token = token } func (this *DrdiciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/endian_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type EndianExpr struct { token *lexer.Token } func (this *EndianExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LITTLE && token_type != lexer.BIG { err := errors.New("token type is not an endian") panic(err) } this.token = token } func (this *EndianExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/expr.go ================================================ package expr import ( "uPIMulator/src/device/linker/lexer" ) type ExprType int const ( CI_OP_CODE ExprType = iota DDCI_OP_CODE DMA_RRI_OP_CODE DRDICI_OP_CODE I_OP_CODE JUMP_OP_CODE LOAD_OP_CODE R_OP_CODE RICI_OP_CODE RR_OP_CODE RRI_OP_CODE RRRI_OP_CODE STORE_OP_CODE SUFFIX CONDITION ENDIAN SECTION_NAME SECTION_TYPE SYMBOL_TYPE NEGATIVE_NUMBER PRIMARY BINARY_ADD BINARY_SUB PROGRAM_COUNTER SRC_REG ) type Expr struct { expr_type ExprType ci_op_code_expr *CiOpCodeExpr ddci_op_code_expr *DdciOpCodeExpr dma_rri_op_code_expr *DmaRriOpCodeExpr drdici_op_code_expr *DrdiciOpCodeExpr i_op_code_expr *IOpCodeExpr jump_op_code_expr *JumpOpCodeExpr load_op_code_expr *LoadOpCodeExpr r_op_code_expr *ROpCodeExpr rici_op_code_expr *RiciOpCodeExpr rr_op_code_expr *RrOpCodeExpr rri_op_code_expr *RriOpCodeExpr rrri_op_code_expr *RrriOpCodeExpr store_op_code_expr *StoreOpCodeExpr suffix_expr *SuffixExpr condition_expr *ConditionExpr endian_expr *EndianExpr section_name_expr *SectionNameExpr section_type_expr *SectionTypeExpr symbol_type_expr *SymbolTypeExpr negative_number_expr *NegativeNumberExpr primary_expr *PrimaryExpr binary_add_expr *BinaryAddExpr binary_sub_expr *BinarySubExpr program_counter_expr *ProgramCounterExpr src_reg_expr *SrcRegExpr } func (this *Expr) InitCiOpCodeExpr(token *lexer.Token) { this.expr_type = CI_OP_CODE this.ci_op_code_expr = new(CiOpCodeExpr) this.ci_op_code_expr.Init(token) } func (this *Expr) InitDdciOpCodeExpr(token *lexer.Token) { this.expr_type = DDCI_OP_CODE this.ddci_op_code_expr = new(DdciOpCodeExpr) this.ddci_op_code_expr.Init(token) } func (this *Expr) InitDmaRriOpCodeExpr(token *lexer.Token) { this.expr_type = DMA_RRI_OP_CODE this.dma_rri_op_code_expr = new(DmaRriOpCodeExpr) this.dma_rri_op_code_expr.Init(token) } func (this *Expr) InitDrdiciOpCodeExpr(token *lexer.Token) { this.expr_type = DRDICI_OP_CODE this.drdici_op_code_expr = new(DrdiciOpCodeExpr) this.drdici_op_code_expr.Init(token) } func (this *Expr) InitIOpCodeExpr(token *lexer.Token) { this.expr_type = I_OP_CODE this.i_op_code_expr = new(IOpCodeExpr) this.i_op_code_expr.Init(token) } func (this *Expr) InitJumpOpCodeExpr(token *lexer.Token) { this.expr_type = JUMP_OP_CODE this.jump_op_code_expr = new(JumpOpCodeExpr) this.jump_op_code_expr.Init(token) } func (this *Expr) InitLoadOpCodeExpr(token *lexer.Token) { this.expr_type = LOAD_OP_CODE this.load_op_code_expr = new(LoadOpCodeExpr) this.load_op_code_expr.Init(token) } func (this *Expr) InitROpCodeExpr(token *lexer.Token) { this.expr_type = R_OP_CODE this.r_op_code_expr = new(ROpCodeExpr) this.r_op_code_expr.Init(token) } func (this *Expr) InitRiciOpCodeExpr(token *lexer.Token) { this.expr_type = RICI_OP_CODE this.rici_op_code_expr = new(RiciOpCodeExpr) this.rici_op_code_expr.Init(token) } func (this *Expr) InitRrOpCodeExpr(token *lexer.Token) { this.expr_type = RR_OP_CODE this.rr_op_code_expr = new(RrOpCodeExpr) this.rr_op_code_expr.Init(token) } func (this *Expr) InitRriOpCodeExpr(token *lexer.Token) { this.expr_type = RRI_OP_CODE this.rri_op_code_expr = new(RriOpCodeExpr) this.rri_op_code_expr.Init(token) } func (this *Expr) InitRrriOpCodeExpr(token *lexer.Token) { this.expr_type = RRRI_OP_CODE this.rrri_op_code_expr = new(RrriOpCodeExpr) this.rrri_op_code_expr.Init(token) } func (this *Expr) InitStoreOpCodeExpr(token *lexer.Token) { this.expr_type = STORE_OP_CODE this.store_op_code_expr = new(StoreOpCodeExpr) this.store_op_code_expr.Init(token) } func (this *Expr) InitSuffixExpr(token *lexer.Token) { this.expr_type = SUFFIX this.suffix_expr = new(SuffixExpr) this.suffix_expr.Init(token) } func (this *Expr) InitConditionExpr(token *lexer.Token) { this.expr_type = CONDITION this.condition_expr = new(ConditionExpr) this.condition_expr.Init(token) } func (this *Expr) InitEndianExpr(token *lexer.Token) { this.expr_type = ENDIAN this.endian_expr = new(EndianExpr) this.endian_expr.Init(token) } func (this *Expr) InitSectionNameExpr(token *lexer.Token) { this.expr_type = SECTION_NAME this.section_name_expr = new(SectionNameExpr) this.section_name_expr.Init(token) } func (this *Expr) InitSectionTypeExpr(token *lexer.Token) { this.expr_type = SECTION_TYPE this.section_type_expr = new(SectionTypeExpr) this.section_type_expr.Init(token) } func (this *Expr) InitSymbolTypeExpr(token *lexer.Token) { this.expr_type = SYMBOL_TYPE this.symbol_type_expr = new(SymbolTypeExpr) this.symbol_type_expr.Init(token) } func (this *Expr) InitNegativeNumberExpr(token *lexer.Token) { this.expr_type = NEGATIVE_NUMBER this.negative_number_expr = new(NegativeNumberExpr) this.negative_number_expr.Init(token) } func (this *Expr) InitPrimaryExpr(token *lexer.Token) { this.expr_type = PRIMARY this.primary_expr = new(PrimaryExpr) this.primary_expr.Init(token) } func (this *Expr) InitBinaryAddExpr(operand1 *Expr, operand2 *Expr) { this.expr_type = BINARY_ADD this.binary_add_expr = new(BinaryAddExpr) this.binary_add_expr.Init(operand1, operand2) } func (this *Expr) InitBinarySubExpr(operand1 *Expr, operand2 *Expr) { this.expr_type = BINARY_SUB this.binary_sub_expr = new(BinarySubExpr) this.binary_sub_expr.Init(operand1, operand2) } func (this *Expr) InitProgramCounterExpr(expr *Expr) { this.expr_type = PROGRAM_COUNTER this.program_counter_expr = new(ProgramCounterExpr) this.program_counter_expr.Init(expr) } func (this *Expr) InitSrcRegExpr(token *lexer.Token) { this.expr_type = SRC_REG this.src_reg_expr = new(SrcRegExpr) this.src_reg_expr.Init(token) } func (this *Expr) ExprType() ExprType { return this.expr_type } func (this *Expr) CiOpCodeExpr() *CiOpCodeExpr { return this.ci_op_code_expr } func (this *Expr) DdciOpCodeExpr() *DdciOpCodeExpr { return this.ddci_op_code_expr } func (this *Expr) DmaRriOpCodeExpr() *DmaRriOpCodeExpr { return this.dma_rri_op_code_expr } func (this *Expr) DrdiciOpCodeExpr() *DrdiciOpCodeExpr { return this.drdici_op_code_expr } func (this *Expr) IOpCodeExpr() *IOpCodeExpr { return this.i_op_code_expr } func (this *Expr) JumpOpCodeExpr() *JumpOpCodeExpr { return this.jump_op_code_expr } func (this *Expr) LoadOpCodeExpr() *LoadOpCodeExpr { return this.load_op_code_expr } func (this *Expr) ROpCodeExpr() *ROpCodeExpr { return this.r_op_code_expr } func (this *Expr) RiciOpCodeExpr() *RiciOpCodeExpr { return this.rici_op_code_expr } func (this *Expr) RrOpCodeExpr() *RrOpCodeExpr { return this.rr_op_code_expr } func (this *Expr) RriOpCodeExpr() *RriOpCodeExpr { return this.rri_op_code_expr } func (this *Expr) RrriOpCodeExpr() *RrriOpCodeExpr { return this.rrri_op_code_expr } func (this *Expr) StoreOpCodeExpr() *StoreOpCodeExpr { return this.store_op_code_expr } func (this *Expr) SuffixExpr() *SuffixExpr { return this.suffix_expr } func (this *Expr) ConditionExpr() *ConditionExpr { return this.condition_expr } func (this *Expr) EndianExpr() *EndianExpr { return this.endian_expr } func (this *Expr) SectionNameExpr() *SectionNameExpr { return this.section_name_expr } func (this *Expr) SectionTypeExpr() *SectionTypeExpr { return this.section_type_expr } func (this *Expr) SymbolTypeExpr() *SymbolTypeExpr { return this.symbol_type_expr } func (this *Expr) NegativeNumberExpr() *NegativeNumberExpr { return this.negative_number_expr } func (this *Expr) PrimaryExpr() *PrimaryExpr { return this.primary_expr } func (this *Expr) BinaryAddExpr() *BinaryAddExpr { return this.binary_add_expr } func (this *Expr) BinarySubExpr() *BinarySubExpr { return this.binary_sub_expr } func (this *Expr) ProgramCounterExpr() *ProgramCounterExpr { return this.program_counter_expr } func (this *Expr) SrcRegExpr() *SrcRegExpr { return this.src_reg_expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/i_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type IOpCodeExpr struct { token *lexer.Token } func (this *IOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.FAULT && token_type != lexer.BKP { err := errors.New("token type is not an I op code") panic(err) } this.token = token } func (this *IOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/jump_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type JumpOpCodeExpr struct { token *lexer.Token } func (this *JumpOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.JEQ && token_type != lexer.JNEQ && token_type != lexer.JZ && token_type != lexer.JNZ && token_type != lexer.JLTU && token_type != lexer.JGTU && token_type != lexer.JLEU && token_type != lexer.JGEU && token_type != lexer.JLTS && token_type != lexer.JGTS && token_type != lexer.JLES && token_type != lexer.JGES && token_type != lexer.JUMP { err := errors.New("token type is not a jump op code") panic(err) } this.token = token } func (this *JumpOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/load_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type LoadOpCodeExpr struct { token *lexer.Token } func (this *LoadOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LBS && token_type != lexer.LBU && token_type != lexer.LD && token_type != lexer.LHS && token_type != lexer.LHU && token_type != lexer.LW { err := errors.New("token type is not a load op code") panic(err) } this.token = token } func (this *LoadOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/negative_number_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type NegativeNumberExpr struct { token *lexer.Token } func (this *NegativeNumberExpr) Init(token *lexer.Token) { if token.TokenType() != lexer.POSITIVIE_NUMBER { err := errors.New("token type is not positive number") panic(err) } this.token = token } func (this *NegativeNumberExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/primary_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type PrimaryExpr struct { token *lexer.Token } func (this *PrimaryExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.POSITIVIE_NUMBER && token_type != lexer.HEX_NUMBER && token_type != lexer.IDENTIFIER { err := errors.New("token type is not positive number, hex number, nor identifier") panic(err) } this.token = token } func (this *PrimaryExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/program_counter_expr.go ================================================ package expr import ( "errors" ) type ProgramCounterExpr struct { expr *Expr } func (this *ProgramCounterExpr) Init(expr *Expr) { expr_type := expr.ExprType() if expr_type != PRIMARY && expr_type != NEGATIVE_NUMBER && expr_type != BINARY_ADD && expr_type != BINARY_SUB { err := errors.New("expr type is not primary, negative number, binary add, nor binary sub") panic(err) } this.expr = expr } func (this *ProgramCounterExpr) Expr() *Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/r_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type ROpCodeExpr struct { token *lexer.Token } func (this *ROpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.TIME && token_type != lexer.NOP { err := errors.New("token type is not an R op code") panic(err) } this.token = token } func (this *ROpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/rici_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type RiciOpCodeExpr struct { token *lexer.Token } func (this *RiciOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ACQUIRE && token_type != lexer.RELEASE && token_type != lexer.BOOT && token_type != lexer.RESUME { err := errors.New("token type is not an RICI op code") panic(err) } this.token = token } func (this *RiciOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/rr_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type RrOpCodeExpr struct { token *lexer.Token } func (this *RrOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.CAO && token_type != lexer.CLO && token_type != lexer.CLS && token_type != lexer.CLZ && token_type != lexer.EXTSB && token_type != lexer.EXTSH && token_type != lexer.EXTUB && token_type != lexer.EXTUH && token_type != lexer.SATS && token_type != lexer.TIME_CFG && token_type != lexer.MOVE && token_type != lexer.NEG && token_type != lexer.NOT { err := errors.New("token type is not an RR op code") panic(err) } this.token = token } func (this *RrOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/rri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type RriOpCodeExpr struct { token *lexer.Token } func (this *RriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ADD && token_type != lexer.ADDC && token_type != lexer.AND && token_type != lexer.ANDN && token_type != lexer.ASR && token_type != lexer.CMPB4 && token_type != lexer.LSL && token_type != lexer.LSL1 && token_type != lexer.LSL1X && token_type != lexer.LSLX && token_type != lexer.LSR && token_type != lexer.LSR1 && token_type != lexer.LSR1X && token_type != lexer.LSRX && token_type != lexer.MUL_SH_SH && token_type != lexer.MUL_SH_SL && token_type != lexer.MUL_SH_UH && token_type != lexer.MUL_SH_UL && token_type != lexer.MUL_SL_SH && token_type != lexer.MUL_SL_SL && token_type != lexer.MUL_SL_UH && token_type != lexer.MUL_SL_UL && token_type != lexer.MUL_UH_UH && token_type != lexer.MUL_UH_UL && token_type != lexer.MUL_UL_UH && token_type != lexer.MUL_UL_UL && token_type != lexer.NAND && token_type != lexer.NOR && token_type != lexer.NXOR && token_type != lexer.OR && token_type != lexer.ORN && token_type != lexer.ROL && token_type != lexer.ROR && token_type != lexer.RSUB && token_type != lexer.RSUBC && token_type != lexer.SUB && token_type != lexer.SUBC && token_type != lexer.XOR && token_type != lexer.CALL { err := errors.New("token type is not an RRI op code") panic(err) } this.token = token } func (this *RriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/rrri_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type RrriOpCodeExpr struct { token *lexer.Token } func (this *RrriOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.LSL_ADD && token_type != lexer.LSL_SUB && token_type != lexer.LSR_ADD && token_type != lexer.ROL_ADD { err := errors.New("token type is not an RRRI op code") panic(err) } this.token = token } func (this *RrriOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/section_name_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type SectionNameExpr struct { token *lexer.Token } func (this *SectionNameExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.ATOMIC && token_type != lexer.BSS && token_type != lexer.DATA && token_type != lexer.DEBUG_ABBREV && token_type != lexer.DEBUG_FRAME && token_type != lexer.DEBUG_INFO && token_type != lexer.DEBUG_LINE && token_type != lexer.DEBUG_LOC && token_type != lexer.DEBUG_RANGES && token_type != lexer.DEBUG_STR && token_type != lexer.DPU_HOST && token_type != lexer.MRAM && token_type != lexer.RODATA && token_type != lexer.STACK_SIZES && token_type != lexer.TEXT { err := errors.New("token type is not a section name") panic(err) } this.token = token } func (this *SectionNameExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/section_type_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type SectionTypeExpr struct { token *lexer.Token } func (this *SectionTypeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.PROGBITS && token_type != lexer.NOBITS { err := errors.New("token type is not a section type") panic(err) } this.token = token } func (this *SectionTypeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/src_reg_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type SrcRegExpr struct { token *lexer.Token } func (this *SrcRegExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.GP_REG && token_type != lexer.ZERO_REG && token_type != lexer.ONE && token_type != lexer.ID && token_type != lexer.ID2 && token_type != lexer.ID4 && token_type != lexer.ID8 && token_type != lexer.LNEG && token_type != lexer.MNEG { err := errors.New("token type is not a src reg") panic(err) } this.token = token } func (this *SrcRegExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/store_op_code_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type StoreOpCodeExpr struct { token *lexer.Token } func (this *StoreOpCodeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.SB && token_type != lexer.SB_ID && token_type != lexer.SD && token_type != lexer.SD_ID && token_type != lexer.SH && token_type != lexer.SH_ID && token_type != lexer.SW && token_type != lexer.SW_ID { err := errors.New("token type is not a store op code") panic(err) } this.token = token } func (this *StoreOpCodeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/suffix_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type SuffixExpr struct { token *lexer.Token } func (this *SuffixExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.S && token_type != lexer.U { err := errors.New("token type is not a suffix") panic(err) } this.token = token } func (this *SuffixExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/expr/symbol_type.go ================================================ package expr import ( "errors" "uPIMulator/src/device/linker/lexer" ) type SymbolTypeExpr struct { token *lexer.Token } func (this *SymbolTypeExpr) Init(token *lexer.Token) { token_type := token.TokenType() if token_type != lexer.FUNCTION && token_type != lexer.OBJECT { err := errors.New("token type is not a symbol type") panic(err) } this.token = token } func (this *SymbolTypeExpr) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/parser.go ================================================ package parser import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" ) type Parser struct { stack *Stack table *Table } func (this *Parser) Init() { this.stack = new(Stack) this.stack.Init() this.table = new(Table) this.table.Init(this.stack) this.RegisterAccessExpr() this.RegisterConcatExpr() this.RegisterBinaryAddExpr() this.RegisterBinarySubExpr() this.RegisterCiOpCodeExpr() this.RegisterConditionExpr() this.RegisterDdciOpCodeExpr() this.RegisterDmaRriOpCodeExpr() this.RegisterDrdiciOpCodeExpr() this.RegisterEndianExpr() this.RegisterIOpCodeExpr() this.RegisterJumpOpCodeExpr() this.RegisterLoadOpCodeExpr() this.RegisterNegativeNumberExpr() this.RegisterPrimaryExpr() this.RegisterProgramCounterExpr() this.RegisterROpCodeExpr() this.RegisterRiciOpCodeExpr() this.RegisterRrOpCodeExpr() this.RegisterRriOpCodeExpr() this.RegisterRrriOpCodeExpr() this.RegisterSectionNameExpr() this.RegisterSectionTypeExpr() this.RegisterSrcRegExpr() this.RegisterStoreOpCodeExpr() this.RegisterSuffixExpr() this.RegisterSymbolTypeExpr() this.RegisterAddrsigStmt() this.RegisterAddrsigSymStmt() this.RegisterAsciiStmt() this.RegisterAscizStmt() this.RegisterByteStmt() this.RegisterCfiDefCfaOffsetStmt() this.RegisterCfiEndprocStmt() this.RegisterCfiOffsetStmt() this.RegisterCfiSectionsStmt() this.RegisterCfiStartprocStmt() this.RegisterFileNumberStmt() this.RegisterFileStringStmt() this.RegisterGlobalStmt() this.RegisterLocIsStmtStmt() this.RegisterLocNumberStmt() this.RegisterLocPrologueEndStmt() this.RegisterLongProgramCounterStmt() this.RegisterLongSectionNameStmt() this.RegisterP2AlignStmt() this.RegisterQuadStmt() this.RegisterSectionIdentifierNumberStmt() this.RegisterSectionIdentifierStmt() this.RegisterSectionStackSizesStmt() this.RegisterSectionStringNumberStmt() this.RegisterSectionStringStmt() this.RegisterSetStmt() this.RegisterShortStmt() this.RegisterSizeStmt() this.RegisterTextStmt() this.RegisterTypeStmt() this.RegisterWeakStmt() this.RegisterZeroDoubleNumberStmt() this.RegisterZeroSingleNumberStmt() this.RegisterCiStmt() this.RegisterDdciStmt() this.RegisterDmaRriStmt() this.RegisterDrdiciStmt() this.RegisterEdriStmt() this.RegisterEriiStmt() this.RegisterErirStmt() this.RegisterErriStmt() this.RegisterIStmt() this.RegisterRciStmt() this.RegisterRiciStmt() this.RegisterRirciStmt() this.RegisterRircStmt() this.RegisterRirStmt() this.RegisterRrciStmt() this.RegisterRrcStmt() this.RegisterRriciStmt() this.RegisterRricStmt() this.RegisterRriStmt() this.RegisterRrrciStmt() this.RegisterRrrcStmt() this.RegisterRrriciStmt() this.RegisterRrriStmt() this.RegisterRrrStmt() this.RegisterRrStmt() this.RegisterRStmt() this.RegisterSErriStmt() this.RegisterSRciStmt() this.RegisterSRirciStmt() this.RegisterSRrciStmt() this.RegisterSRrcStmt() this.RegisterSRriciStmt() this.RegisterSRricStmt() this.RegisterSRriStmt() this.RegisterSRrrciStmt() this.RegisterSRrrcStmt() this.RegisterSRrriciStmt() this.RegisterSRrriStmt() this.RegisterSRrrStmt() this.RegisterSRrStmt() this.RegisterSRStmt() this.RegisterNopStmt() this.RegisterBkpStmt() this.RegisterBootRiStmt() this.RegisterCallRiStmt() this.RegisterCallRrStmt() this.RegisterDivStepDrdiStmt() this.RegisterJeqRiiStmt() this.RegisterJeqRriStmt() this.RegisterJnzRiStmt() this.RegisterJumpIStmt() this.RegisterJumpRStmt() this.RegisterLbsRriStmt() this.RegisterLbsSRriStmt() this.RegisterLdDriStmt() this.RegisterMovdDdStmt() this.RegisterMoveRiciStmt() this.RegisterMoveRiStmt() this.RegisterMoveSRiciStmt() this.RegisterMoveSRiStmt() this.RegisterSbIdRiiStmt() this.RegisterSbIdRiStmt() this.RegisterSbRirStmt() this.RegisterSdRidStmt() this.RegisterStopStmt() this.RegisterTimeCfgRStmt() this.RegisterLabelStmt() } func (this *Parser) Parse(token_stream *lexer.TokenStream) *Ast { for pos := 0; pos < token_stream.Length(); pos++ { token := token_stream.Get(pos) this.ReduceExpr(token) if token.TokenType() != lexer.NEW_LINE { stack_item := new(StackItem) stack_item.InitToken(token) this.stack.Push(stack_item) } else { this.ReduceStmt(token) if !this.stack.AreStmts() { err := errors.New("stack are not stmts") panic(err) } } } if !this.stack.CanAccept() { err := errors.New("stack cannot be accepted") panic(err) } return this.stack.Accept() } func (this *Parser) ReduceExpr(token *lexer.Token) { for { reducible_expr_rule, stack_items := this.table.FindReducibleExprRule(token) if reducible_expr_rule != nil { stack_item := reducible_expr_rule.Reduce(stack_items, token) this.stack.Pop(len(stack_items)) this.stack.Push(stack_item) } else { break } } } func (this *Parser) ReduceStmt(token *lexer.Token) { for { reducible_stmt_rule, stack_items := this.table.FindReducibleStmtRule(token) if reducible_stmt_rule != nil { stack_item := reducible_stmt_rule.Reduce(stack_items, token) this.stack.Pop(len(stack_items)) this.stack.Push(stack_item) } else { break } } } func (this *Parser) RegisterAccessExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.IDENTIFIER && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token1 := stack_items[0].Token() token2 := stack_items[1].Token() attribute := token1.Attribute() + token2.Attribute() token := new(lexer.Token) token.Init(lexer.IDENTIFIER, attribute) stack_item := new(StackItem) stack_item.InitToken(token) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterConcatExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.NEGATIVE_NUMBER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[1].Expr() negative_number_expr := operand2.NegativeNumberExpr() token := negative_number_expr.Token() primary_expr := new(expr.Expr) primary_expr.InitPrimaryExpr(token) binary_sub_expr := new(expr.Expr) binary_sub_expr.InitBinarySubExpr(operand1, primary_expr) stack_item := new(StackItem) stack_item.InitExpr(binary_sub_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterBinaryAddExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PLUS && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PRIMARY { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[2].Expr() binary_add_expr := new(expr.Expr) binary_add_expr.InitBinaryAddExpr(operand1, operand2) stack_item := new(StackItem) stack_item.InitExpr(binary_add_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterBinarySubExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PRIMARY && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MINUS && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PRIMARY { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { operand1 := stack_items[0].Expr() operand2 := stack_items[2].Expr() binary_sub_expr := new(expr.Expr) binary_sub_expr.InitBinarySubExpr(operand1, operand2) stack_item := new(StackItem) stack_item.InitExpr(binary_sub_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterCiOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.STOP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() ci_op_code_expr := new(expr.Expr) ci_op_code_expr.InitCiOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(ci_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDdciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.MOVD || token_type == lexer.SWAPD { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() ddci_op_code_expr := new(expr.Expr) ddci_op_code_expr.InitDdciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(ddci_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDmaRriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LDMA || token_type == lexer.LDMAI || token_type == lexer.SDMA { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() dma_rri_op_code_expr := new(expr.Expr) dma_rri_op_code_expr.InitDmaRriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(dma_rri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterDrdiciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.DIV_STEP || token_type == lexer.MUL_STEP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() drdici_op_code_expr := new(expr.Expr) drdici_op_code_expr.InitDrdiciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(drdici_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterConditionExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.TRUE || token_type == lexer.FALSE || token_type == lexer.Z || token_type == lexer.NZ || token_type == lexer.E || token_type == lexer.O || token_type == lexer.PL || token_type == lexer.MI || token_type == lexer.OV || token_type == lexer.NOV || token_type == lexer.C || token_type == lexer.NC || token_type == lexer.SZ || token_type == lexer.SNZ || token_type == lexer.SPL || token_type == lexer.SMI || token_type == lexer.SO || token_type == lexer.SE || token_type == lexer.NC5 || token_type == lexer.NC5 || token_type == lexer.NC6 || token_type == lexer.NC7 || token_type == lexer.NC8 || token_type == lexer.NC9 || token_type == lexer.NC10 || token_type == lexer.NC11 || token_type == lexer.NC12 || token_type == lexer.NC13 || token_type == lexer.NC14 || token_type == lexer.MAX || token_type == lexer.NMAX || token_type == lexer.SH32 || token_type == lexer.NSH32 || token_type == lexer.EQ || token_type == lexer.NEQ || token_type == lexer.LTU || token_type == lexer.LEU || token_type == lexer.GTU || token_type == lexer.GEU || token_type == lexer.LTS || token_type == lexer.LES || token_type == lexer.GTS || token_type == lexer.GES || token_type == lexer.XZ || token_type == lexer.XNZ || token_type == lexer.XLEU || token_type == lexer.XGTU || token_type == lexer.XLES || token_type == lexer.XGTS || token_type == lexer.SMALL || token_type == lexer.LARGE { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() condition_expr := new(expr.Expr) condition_expr.InitConditionExpr(token) stack_item := new(StackItem) stack_item.InitExpr(condition_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterEndianExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LITTLE || token_type == lexer.BIG { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() endian_expr := new(expr.Expr) endian_expr.InitEndianExpr(token) stack_item := new(StackItem) stack_item.InitExpr(endian_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterIOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.FAULT || token_type == lexer.BKP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() i_op_code_expr := new(expr.Expr) i_op_code_expr.InitIOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(i_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterJumpOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.JEQ || token_type == lexer.JNEQ || token_type == lexer.JZ || token_type == lexer.JNZ || token_type == lexer.JLTU || token_type == lexer.JGTU || token_type == lexer.JLEU || token_type == lexer.JGEU || token_type == lexer.JLTS || token_type == lexer.JGTS || token_type == lexer.JLES || token_type == lexer.JGES || token_type == lexer.JUMP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() jump_op_code_expr := new(expr.Expr) jump_op_code_expr.InitJumpOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(jump_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterLoadOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LBS || token_type == lexer.LBU || token_type == lexer.LD || token_type == lexer.LHS || token_type == lexer.LHU || token_type == lexer.LW { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() load_op_code_expr := new(expr.Expr) load_op_code_expr.InitLoadOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(load_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterNegativeNumberExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.MINUS && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.POSITIVIE_NUMBER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() negativer_number_expr := new(expr.Expr) negativer_number_expr.InitNegativeNumberExpr(token) stack_item := new(StackItem) stack_item.InitExpr(negativer_number_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterPrimaryExpr() { precedence := map[lexer.TokenType]bool{lexer.IDENTIFIER: true} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.POSITIVIE_NUMBER || token_type == lexer.HEX_NUMBER || token_type == lexer.IDENTIFIER { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.Expr) primary_expr.InitPrimaryExpr(token) stack_item := new(StackItem) stack_item.InitExpr(primary_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterProgramCounterExpr() { precedence := map[lexer.TokenType]bool{lexer.PLUS: true, lexer.MINUS: true} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR { expr_type := stack_items[0].Expr().ExprType() if expr_type == expr.PRIMARY || expr_type == expr.NEGATIVE_NUMBER || expr_type == expr.BINARY_ADD || expr_type == expr.BINARY_SUB { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[0].Expr() program_counter_expr := new(expr.Expr) program_counter_expr.InitProgramCounterExpr(expr_) stack_item := new(StackItem) stack_item.InitExpr(program_counter_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterROpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.TIME || token_type == lexer.NOP { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() r_op_code_expr := new(expr.Expr) r_op_code_expr.InitROpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(r_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRiciOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ACQUIRE || token_type == lexer.RELEASE || token_type == lexer.BOOT || token_type == lexer.RESUME { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rici_op_code_expr := new(expr.Expr) rici_op_code_expr.InitRiciOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rici_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRrOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.CAO || token_type == lexer.CLO || token_type == lexer.CLS || token_type == lexer.CLZ || token_type == lexer.EXTSB || token_type == lexer.EXTSH || token_type == lexer.EXTUB || token_type == lexer.EXTUH || token_type == lexer.SATS || token_type == lexer.TIME_CFG || token_type == lexer.MOVE || token_type == lexer.NEG || token_type == lexer.NOT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rr_op_code_expr := new(expr.Expr) rr_op_code_expr.InitRrOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rr_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ADD || token_type == lexer.ADDC || token_type == lexer.AND || token_type == lexer.ANDN || token_type == lexer.ASR || token_type == lexer.CMPB4 || token_type == lexer.LSL || token_type == lexer.LSL1 || token_type == lexer.LSL1X || token_type == lexer.LSLX || token_type == lexer.LSR || token_type == lexer.LSR1 || token_type == lexer.LSR1X || token_type == lexer.LSRX || token_type == lexer.MUL_SH_SH || token_type == lexer.MUL_SH_SL || token_type == lexer.MUL_SH_UH || token_type == lexer.MUL_SH_UL || token_type == lexer.MUL_SL_SH || token_type == lexer.MUL_SL_SL || token_type == lexer.MUL_SL_UH || token_type == lexer.MUL_SL_UL || token_type == lexer.MUL_UH_UH || token_type == lexer.MUL_UH_UL || token_type == lexer.MUL_UL_UH || token_type == lexer.MUL_UL_UL || token_type == lexer.NAND || token_type == lexer.NOR || token_type == lexer.NXOR || token_type == lexer.OR || token_type == lexer.ORN || token_type == lexer.ROL || token_type == lexer.ROR || token_type == lexer.RSUB || token_type == lexer.RSUBC || token_type == lexer.SUB || token_type == lexer.SUBC || token_type == lexer.XOR || token_type == lexer.CALL { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rri_op_code_expr := new(expr.Expr) rri_op_code_expr.InitRriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterRrriOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.LSL_ADD || token_type == lexer.LSL_SUB || token_type == lexer.LSR_ADD || token_type == lexer.ROL_ADD { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() rrri_op_code_expr := new(expr.Expr) rrri_op_code_expr.InitRrriOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(rrri_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterStoreOpCodeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.SB || token_type == lexer.SB_ID || token_type == lexer.SD || token_type == lexer.SD_ID || token_type == lexer.SH || token_type == lexer.SH_ID || token_type == lexer.SW || token_type == lexer.SW_ID { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() store_op_code_expr := new(expr.Expr) store_op_code_expr.InitStoreOpCodeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(store_op_code_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSuffixExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.S || token_type == lexer.U { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() suffix_expr := new(expr.Expr) suffix_expr.InitSuffixExpr(token) stack_item := new(StackItem) stack_item.InitExpr(suffix_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSectionNameExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.ATOMIC || token_type == lexer.BSS || token_type == lexer.DATA || token_type == lexer.DEBUG_ABBREV || token_type == lexer.DEBUG_FRAME || token_type == lexer.DEBUG_INFO || token_type == lexer.DEBUG_LINE || token_type == lexer.DEBUG_LOC || token_type == lexer.DEBUG_RANGES || token_type == lexer.DEBUG_STR || token_type == lexer.DPU_HOST || token_type == lexer.MRAM || token_type == lexer.RODATA || token_type == lexer.STACK_SIZES || token_type == lexer.TEXT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() section_name_expr := new(expr.Expr) section_name_expr.InitSectionNameExpr(token) stack_item := new(StackItem) stack_item.InitExpr(section_name_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSectionTypeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.PROGBITS || token_type == lexer.NOBITS { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() section_type_expr := new(expr.Expr) section_type_expr.InitSectionTypeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(section_type_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSrcRegExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.GP_REG || token_type == lexer.ZERO_REG || token_type == lexer.ONE || token_type == lexer.ID || token_type == lexer.ID2 || token_type == lexer.ID4 || token_type == lexer.ID8 || token_type == lexer.LNEG || token_type == lexer.MNEG { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() src_reg_expr := new(expr.Expr) src_reg_expr.InitSrcRegExpr(token) stack_item := new(StackItem) stack_item.InitExpr(src_reg_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterSymbolTypeExpr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN { token_type := stack_items[0].Token().TokenType() if token_type == lexer.FUNCTION || token_type == lexer.OBJECT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() symbol_type_expr := new(expr.Expr) symbol_type_expr.InitSymbolTypeExpr(token) stack_item := new(StackItem) stack_item.InitExpr(symbol_type_expr) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddExprRule(rule) } func (this *Parser) RegisterAddrsigStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ADDRSIG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { addrsig_stmt := new(stmt.Stmt) addrsig_stmt.InitAddrsigStmt() stack_item := new(StackItem) stack_item.InitStmt(addrsig_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAddrsigSymStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ADDRSIG_SYM && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() addrsig_sym_stmt := new(stmt.Stmt) addrsig_sym_stmt.InitAddrsigSymStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(addrsig_sym_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAsciiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ASCII && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() ascii_stmt := new(stmt.Stmt) ascii_stmt.InitAsciiStmt(token) stack_item := new(StackItem) stack_item.InitStmt(ascii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterAscizStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ASCIZ && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() asciz_stmt := new(stmt.Stmt) asciz_stmt.InitAscizStmt(token) stack_item := new(StackItem) stack_item.InitStmt(asciz_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterByteStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.BYTE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() byte_stmt := new(stmt.Stmt) byte_stmt.InitByteStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(byte_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiDefCfaOffsetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_DEF_CFA_OFFSET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() cfi_def_cfa_offset_stmt := new(stmt.Stmt) cfi_def_cfa_offset_stmt.InitCfiDefCfaOffsetStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(cfi_def_cfa_offset_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiEndprocStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_ENDPROC { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { cfi_endproc_stmt := new(stmt.Stmt) cfi_endproc_stmt.InitCfiEndprocStmt() stack_item := new(StackItem) stack_item.InitStmt(cfi_endproc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiOffsetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_OFFSET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() cfi_offset_stmt := new(stmt.Stmt) cfi_offset_stmt.InitCfiOffsetStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(cfi_offset_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiSectionsStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_SECTIONS && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() cfi_sections_stmt := new(stmt.Stmt) cfi_sections_stmt.InitCfiSectionsStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(cfi_sections_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCfiStartprocStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CFI_STARTPROC { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { cfi_startproc_stmt := new(stmt.Stmt) cfi_startproc_stmt.InitCfiStartprocStmt() stack_item := new(StackItem) stack_item.InitStmt(cfi_startproc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterFileNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.FILE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.STRING && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() token1 := stack_items[2].Token() token2 := stack_items[3].Token() file_number_stmt := new(stmt.Stmt) file_number_stmt.InitFileNumberStmt(expr_, token1, token2) stack_item := new(StackItem) stack_item.InitStmt(file_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterFileStringStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.FILE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[1].Token() file_string_stmt := new(stmt.Stmt) file_string_stmt.InitFileStringStmt(token) stack_item := new(StackItem) stack_item.InitStmt(file_string_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterGlobalStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.GLOBL && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() global_stmt := new(stmt.Stmt) global_stmt.InitGlobalStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(global_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocIsStmtStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.IS_STMT && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() expr4 := stack_items[5].Expr() loc_is_stmt_stmt := new(stmt.Stmt) loc_is_stmt_stmt.InitLocIsStmtStmt(expr1, expr2, expr3, expr4) stack_item := new(StackItem) stack_item.InitStmt(loc_is_stmt_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() loc_number_stmt := new(stmt.Stmt) loc_number_stmt.InitLocNumberStmt(expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(loc_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLocPrologueEndStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LOC && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.PROLOGUE_END { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() expr3 := stack_items[3].Expr() loc_prologue_end_stmt := new(stmt.Stmt) loc_prologue_end_stmt.InitLocPrologueEndStmt(expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(loc_prologue_end_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLongProgramCounterStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LONG && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() long_program_counter_stmt := new(stmt.Stmt) long_program_counter_stmt.InitLongProgramCounterStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(long_program_counter_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLongSectionNameStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LONG && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() long_section_name_stmt := new(stmt.Stmt) long_section_name_stmt.InitLongSectionNameStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(long_section_name_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterP2AlignStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.P2ALIGN && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() p2align_stmt := new(stmt.Stmt) p2align_stmt.InitP2AlignStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(p2align_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterQuadStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.QUAD && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() quad_stmt := new(stmt.Stmt) quad_stmt.InitQuadStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(quad_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionIdentifierNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.STRING && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SECTION_TYPE && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() token := stack_items[4].Token() expr3 := stack_items[6].Expr() expr4 := stack_items[8].Expr() section_identifier_number_stmt := new(stmt.Stmt) section_identifier_number_stmt.InitSectionIdentifierNumberStmt( expr1, expr2, token, expr3, expr4, ) stack_item := new(StackItem) stack_item.InitStmt(section_identifier_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionIdentifierStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.STRING && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SECTION_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[2].Expr() token := stack_items[4].Token() expr3 := stack_items[6].Expr() section_identifier_stmt := new(stmt.Stmt) section_identifier_stmt.InitSectionIdentifierStmt(expr1, expr2, token, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_identifier_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStackSizesStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.SECTION_NAME && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[3].Token() expr1 := stack_items[5].Expr() expr2 := stack_items[7].Expr() expr3 := stack_items[8].Expr() section_stack_sizes_stmt := new(stmt.Stmt) section_stack_sizes_stmt.InitSectionStackSizesStmt(token, expr1, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_stack_sizes_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStringNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() token := stack_items[3].Token() expr2 := stack_items[5].Expr() expr3 := stack_items[7].Expr() section_string_number_stmt := new(stmt.Stmt) section_string_number_stmt.InitSectionStringNumberStmt(expr1, token, expr2, expr3) stack_item := new(StackItem) stack_item.InitStmt(section_string_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSectionStringStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SECTION && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SECTION_NAME && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.STRING && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SECTION_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() token := stack_items[3].Token() expr2 := stack_items[5].Expr() section_string_stmt := new(stmt.Stmt) section_string_stmt.InitSectionStringStmt(expr1, token, expr2) stack_item := new(StackItem) stack_item.InitStmt(section_string_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSetStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SET && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() set_stmt := new(stmt.Stmt) set_stmt.InitSetStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(set_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterShortStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SHORT && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() short_stmt := new(stmt.Stmt) short_stmt.InitShortStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(short_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSizeStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SIZE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() size_stmt := new(stmt.Stmt) size_stmt.InitSizeStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(size_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTextStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.SECTION_NAME { expr_ := stack_items[0].Expr() if expr_.SectionNameExpr().Token().TokenType() == lexer.TEXT { return true } else { return false } } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { text_stmt := new(stmt.Stmt) text_stmt.InitTextStmt() stack_item := new(StackItem) stack_item.InitStmt(text_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTypeStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.TYPE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SYMBOL_TYPE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() type_stmt := new(stmt.Stmt) type_stmt.InitTypeStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(type_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterWeakStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.WEAK && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() weak_stmt := new(stmt.Stmt) weak_stmt.InitWeakStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(weak_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterZeroDoubleNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ZERO_DIRECTIVE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr1 := stack_items[1].Expr() expr2 := stack_items[3].Expr() zero_double_number_stmt := new(stmt.Stmt) zero_double_number_stmt.InitZeroDoubleNumberStmt(expr1, expr2) stack_item := new(StackItem) stack_item.InitStmt(zero_double_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterZeroSingleNumberStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.ZERO_DIRECTIVE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[1].Expr() zero_single_number_stmt := new(stmt.Stmt) zero_single_number_stmt.InitZeroSingleNumberStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(zero_single_number_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.CI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.CONDITION && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() condition := stack_items[1].Expr() pc := stack_items[3].Expr() ci_stmt := new(stmt.Stmt) ci_stmt.InitCiStmt(op_code, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(ci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDdciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DDCI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() db := stack_items[3].Token() condition := stack_items[5].Expr() pc := stack_items[7].Expr() ddci_stmt := new(stmt.Stmt) ddci_stmt.InitDdciStmt(op_code, dc, db, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(ddci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDmaRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DMA_RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() rb := stack_items[3].Expr() pc := stack_items[5].Expr() dma_rri_stmt := new(stmt.Stmt) dma_rri_stmt.InitDmaRriStmt(op_code, ra, rb, pc) stack_item := new(StackItem) stack_item.InitStmt(dma_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDrdiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 12 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DRDICI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.CONDITION && stack_items[10].StackItemType() == TOKEN && stack_items[10].Token().TokenType() == lexer.COMMA && stack_items[11].StackItemType() == EXPR && stack_items[11].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() db := stack_items[5].Token() imm := stack_items[7].Expr() condition := stack_items[9].Expr() pc := stack_items[11].Expr() drdici_stmt := new(stmt.Stmt) drdici_stmt.InitDrdiciStmt(op_code, dc, ra, db, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(drdici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEdriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() dc := stack_items[3].Token() ra := stack_items[5].Expr() off := stack_items[7].Expr() edri_stmt := new(stmt.Stmt) edri_stmt.InitEdriStmt(op_code, endian, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(edri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEridStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() db := stack_items[7].Token() edri_stmt := new(stmt.Stmt) edri_stmt.InitEridStmt(op_code, endian, ra, off, db) stack_item := new(StackItem) stack_item.InitStmt(edri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterEriiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() imm := stack_items[7].Expr() erii_stmt := new(stmt.Stmt) erii_stmt.InitEriiStmt(op_code, endian, ra, off, imm) stack_item := new(StackItem) stack_item.InitStmt(erii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterErirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() rb := stack_items[7].Expr() erir_stmt := new(stmt.Stmt) erir_stmt.InitErirStmt(op_code, endian, ra, off, rb) stack_item := new(StackItem) stack_item.InitStmt(erir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterErriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.ENDIAN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() endian := stack_items[1].Expr() rc := stack_items[3].Expr() ra := stack_items[5].Expr() off := stack_items[7].Expr() erri_stmt := new(stmt.Stmt) erri_stmt.InitErriStmt(op_code, endian, rc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(erri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterIStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.I_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() imm := stack_items[1].Expr() i_stmt := new(stmt.Stmt) i_stmt.InitIStmt(op_code, imm) stack_item := new(StackItem) stack_item.InitStmt(i_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.CONDITION && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() condition := stack_items[3].Expr() pc := stack_items[5].Expr() rci_stmt := new(stmt.Stmt) rci_stmt.InitRciStmt(op_code, rc, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RICI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() rici_stmt := new(stmt.Stmt) rici_stmt.InitRiciStmt(op_code, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRirciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rirci_stmt := new(stmt.Stmt) rirci_stmt.InitRirciStmt(op_code, rc, imm, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rirci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRircStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() condition := stack_items[7].Expr() rirc_stmt := new(stmt.Stmt) rirc_stmt.InitRircStmt(op_code, rc, imm, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(rirc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() ra := stack_items[5].Expr() rir_stmt := new(stmt.Stmt) rir_stmt.InitRirStmt(op_code, rc, imm, ra) stack_item := new(StackItem) stack_item.InitStmt(rir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() rrci_stmt := new(stmt.Stmt) rrci_stmt.InitRrciStmt(op_code, rc, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() condition := stack_items[5].Expr() rrc_stmt := new(stmt.Stmt) rrc_stmt.InitRrcStmt(op_code, rc, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(rrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rrici_stmt := new(stmt.Stmt) rrici_stmt.InitRriciStmt(op_code, rc, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRricStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() condition := stack_items[7].Expr() rric_stmt := new(stmt.Stmt) rric_stmt.InitRricStmt(op_code, rc, ra, imm, condition) stack_item := new(StackItem) stack_item.InitStmt(rric_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() imm := stack_items[5].Expr() rri_stmt := new(stmt.Stmt) rri_stmt.InitRriStmt(op_code, rc, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 10 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() condition := stack_items[7].Expr() pc := stack_items[9].Expr() rrrci_stmt := new(stmt.Stmt) rrrci_stmt.InitRrrciStmt(op_code, rc, ra, rb, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() condition := stack_items[7].Expr() rrrc_stmt := new(stmt.Stmt) rrrc_stmt.InitRrrcStmt(op_code, rc, ra, rb, condition) stack_item := new(StackItem) stack_item.InitStmt(rrrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 12 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[8].StackItemType() == TOKEN && stack_items[8].Token().TokenType() == lexer.COMMA && stack_items[9].StackItemType() == EXPR && stack_items[9].Expr().ExprType() == expr.CONDITION && stack_items[10].StackItemType() == TOKEN && stack_items[10].Token().TokenType() == lexer.COMMA && stack_items[11].StackItemType() == EXPR && stack_items[11].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() imm := stack_items[7].Expr() condition := stack_items[9].Expr() pc := stack_items[11].Expr() rrrici_stmt := new(stmt.Stmt) rrrici_stmt.InitRrriciStmt(op_code, rc, ra, rb, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(rrrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() imm := stack_items[7].Expr() rrri_stmt := new(stmt.Stmt) rrri_stmt.InitRrriStmt(op_code, rc, ra, rb, imm) stack_item := new(StackItem) stack_item.InitStmt(rrri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rb := stack_items[5].Expr() rrr_stmt := new(stmt.Stmt) rrr_stmt.InitRrrStmt(op_code, rc, ra, rb) stack_item := new(StackItem) stack_item.InitStmt(rrr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() rr_stmt := new(stmt.Stmt) rr_stmt.InitRrStmt(op_code, rc, ra) stack_item := new(StackItem) stack_item.InitStmt(rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() r_stmt := new(stmt.Stmt) r_stmt.InitRStmt(op_code, rc) stack_item := new(StackItem) stack_item.InitStmt(r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSErriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == EXPR && stack_items[2].Expr().ExprType() == expr.ENDIAN && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.PAIR_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() endian := stack_items[2].Expr() dc := stack_items[4].Token() ra := stack_items[6].Expr() off := stack_items[8].Expr() s_erri_stmt := new(stmt.Stmt) s_erri_stmt.InitSErriStmt(op_code, suffix, endian, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(s_erri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.CONDITION && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() condition := stack_items[4].Expr() pc := stack_items[6].Expr() s_rci_stmt := new(stmt.Stmt) s_rci_stmt.InitSRciStmt(op_code, suffix, dc, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRirciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() ra := stack_items[6].Expr() condition := stack_items[8].Expr() pc := stack_items[10].Expr() s_rirci_stmt := new(stmt.Stmt) s_rirci_stmt.InitSRirciStmt(op_code, suffix, dc, imm, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rirci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRircStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() ra := stack_items[6].Expr() condition := stack_items[8].Expr() s_rirc_stmt := new(stmt.Stmt) s_rirc_stmt.InitSRircStmt(op_code, suffix, dc, imm, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rirc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() condition := stack_items[6].Expr() pc := stack_items[8].Expr() s_rrci_stmt := new(stmt.Stmt) s_rrci_stmt.InitSRrciStmt(op_code, suffix, dc, ra, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() condition := stack_items[6].Expr() s_rrc_stmt := new(stmt.Stmt) s_rrc_stmt.InitSRrcStmt(op_code, suffix, dc, ra, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() condition := stack_items[8].Expr() pc := stack_items[10].Expr() s_rrici_stmt := new(stmt.Stmt) s_rrici_stmt.InitSRriciStmt(op_code, suffix, dc, ra, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRricStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() condition := stack_items[8].Expr() s_rric_stmt := new(stmt.Stmt) s_rric_stmt.InitSRricStmt(op_code, suffix, dc, ra, imm, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rric_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() imm := stack_items[6].Expr() s_rri_stmt := new(stmt.Stmt) s_rri_stmt.InitSRriStmt(op_code, suffix, dc, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(s_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 11 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() condition := stack_items[7].Expr() pc := stack_items[10].Expr() s_rrrci_stmt := new(stmt.Stmt) s_rrrci_stmt.InitSRrrciStmt(op_code, suffix, dc, ra, rb, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrrci_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrcStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.CONDITION { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() condition := stack_items[7].Expr() s_rrrc_stmt := new(stmt.Stmt) s_rrrc_stmt.InitSRrrcStmt(op_code, suffix, dc, ra, rb, condition) stack_item := new(StackItem) stack_item.InitStmt(s_rrrc_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrriciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 13 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[9].StackItemType() == TOKEN && stack_items[9].Token().TokenType() == lexer.COMMA && stack_items[10].StackItemType() == EXPR && stack_items[10].Expr().ExprType() == expr.CONDITION && stack_items[11].StackItemType() == TOKEN && stack_items[11].Token().TokenType() == lexer.COMMA && stack_items[12].StackItemType() == EXPR && stack_items[12].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() imm := stack_items[8].Expr() condition := stack_items[10].Expr() pc := stack_items[12].Expr() s_rrrici_stmt := new(stmt.Stmt) s_rrrici_stmt.InitSRrriciStmt(op_code, suffix, dc, ra, rb, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(s_rrrici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() imm := stack_items[8].Expr() s_rrri_stmt := new(stmt.Stmt) s_rrri_stmt.InitSRrriStmt(op_code, suffix, dc, ra, rb, imm) stack_item := new(StackItem) stack_item.InitStmt(s_rrri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() rb := stack_items[6].Expr() s_rrr_stmt := new(stmt.Stmt) s_rrr_stmt.InitSRrrStmt(op_code, suffix, dc, ra, rb) stack_item := new(StackItem) stack_item.InitStmt(s_rrr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() s_rr_stmt := new(stmt.Stmt) s_rr_stmt.InitSRrStmt(op_code, suffix, dc, ra) stack_item := new(StackItem) stack_item.InitStmt(s_rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() s_r_stmt := new(stmt.Stmt) s_r_stmt.InitSRStmt(op_code, suffix, dc) stack_item := new(StackItem) stack_item.InitStmt(s_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterNopStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.R_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() if op_code.ROpCodeExpr().Token().TokenType() != lexer.NOP { err := errors.New("op code is not NOP") panic(err) } nop_stmt := new(stmt.Stmt) nop_stmt.InitNopStmt(op_code) stack_item := new(StackItem) stack_item.InitStmt(nop_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterBkpStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.I_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() if op_code.IOpCodeExpr().Token().TokenType() != lexer.BKP { err := errors.New("op code is not BKP") panic(err) } bkp_stmt := new(stmt.Stmt) bkp_stmt.InitBkpStmt() stack_item := new(StackItem) stack_item.InitStmt(bkp_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterBootRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RICI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RiciOpCodeExpr().Token().TokenType() if token_type != lexer.BOOT && token_type != lexer.RESUME { err := errors.New("op code is not BOOT nor RESUME") panic(err) } boot_ri_stmt := new(stmt.Stmt) boot_ri_stmt.InitBootRiStmt(op_code, ra, imm) stack_item := new(StackItem) stack_item.InitStmt(boot_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCallRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RriOpCodeExpr().Token().TokenType() if token_type != lexer.CALL { err := errors.New("op code is not CALL") panic(err) } call_ri_stmt := new(stmt.Stmt) call_ri_stmt.InitCallRiStmt(rc, imm) stack_item := new(StackItem) stack_item.InitStmt(call_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterCallRrStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RRI_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() token_type := op_code.RriOpCodeExpr().Token().TokenType() if token_type != lexer.CALL { err := errors.New("op code is not CALL") panic(err) } call_rr_stmt := new(stmt.Stmt) call_rr_stmt.InitCallRrStmt(rc, ra) stack_item := new(StackItem) stack_item.InitStmt(call_rr_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterDivStepDrdiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DRDICI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() db := stack_items[5].Token() pc := stack_items[7].Expr() div_step_drdi_stmt := new(stmt.Stmt) div_step_drdi_stmt.InitDivStepDrdiStmt(op_code, dc, ra, db, pc) stack_item := new(StackItem) stack_item.InitStmt(div_step_drdi_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJeqRiiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() imm := stack_items[3].Expr() pc := stack_items[5].Expr() jeq_rii_stmt := new(stmt.Stmt) jeq_rii_stmt.InitJeqRiiStmt(op_code, ra, imm, pc) stack_item := new(StackItem) stack_item.InitStmt(jeq_rii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJeqRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() rb := stack_items[3].Expr() pc := stack_items[5].Expr() jeq_rri_stmt := new(stmt.Stmt) jeq_rri_stmt.InitJeqRriStmt(op_code, ra, rb, pc) stack_item := new(StackItem) stack_item.InitStmt(jeq_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJnzRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() pc := stack_items[3].Expr() jnz_ri_stmt := new(stmt.Stmt) jnz_ri_stmt.InitJnzRiStmt(op_code, ra, pc) stack_item := new(StackItem) stack_item.InitStmt(jnz_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJumpIStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() pc := stack_items[1].Expr() token_type := op_code.JumpOpCodeExpr().Token().TokenType() if token_type != lexer.JUMP { err := errors.New("op code is not JUMP") panic(err) } jump_i_stmt := new(stmt.Stmt) jump_i_stmt.InitJumpIStmt(pc) stack_item := new(StackItem) stack_item.InitStmt(jump_i_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterJumpRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.JUMP_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() token_type := op_code.JumpOpCodeExpr().Token().TokenType() if token_type != lexer.JUMP { err := errors.New("op code is not JUMP") panic(err) } jump_r_stmt := new(stmt.Stmt) jump_r_stmt.InitJumpRStmt(ra) stack_item := new(StackItem) stack_item.InitStmt(jump_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLbsRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() ra := stack_items[3].Expr() off := stack_items[5].Expr() lbs_rri_stmt := new(stmt.Stmt) lbs_rri_stmt.InitLbsRriStmt(op_code, rc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(lbs_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLbsSRriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.SRC_REG && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() ra := stack_items[4].Expr() off := stack_items[6].Expr() lbs_s_rri_stmt := new(stmt.Stmt) lbs_s_rri_stmt.InitLbsSRriStmt(op_code, suffix, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(lbs_s_rri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLdDriStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.LOAD_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.SRC_REG && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() ra := stack_items[3].Expr() off := stack_items[5].Expr() ld_dri_stmt := new(stmt.Stmt) ld_dri_stmt.InitLdDriStmt(op_code, dc, ra, off) stack_item := new(StackItem) stack_item.InitStmt(ld_dri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMovdDdStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.DDCI_OP_CODE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PAIR_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() dc := stack_items[1].Token() db := stack_items[3].Token() movd_dd_stmt := new(stmt.Stmt) movd_dd_stmt.InitMovdDdStmt(op_code, dc, db) stack_item := new(StackItem) stack_item.InitStmt(movd_dd_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 8 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.CONDITION && stack_items[6].StackItemType() == TOKEN && stack_items[6].Token().TokenType() == lexer.COMMA && stack_items[7].StackItemType() == EXPR && stack_items[7].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() condition := stack_items[5].Expr() pc := stack_items[7].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_rici_stmt := new(stmt.Stmt) move_rici_stmt.InitMoveRiciStmt(rc, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(move_rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() rc := stack_items[1].Expr() imm := stack_items[3].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_ri_stmt := new(stmt.Stmt) move_ri_stmt.InitMoveRiStmt(rc, imm) stack_item := new(StackItem) stack_item.InitStmt(move_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveSRiciStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 9 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.COMMA && stack_items[6].StackItemType() == EXPR && stack_items[6].Expr().ExprType() == expr.CONDITION && stack_items[7].StackItemType() == TOKEN && stack_items[7].Token().TokenType() == lexer.COMMA && stack_items[8].StackItemType() == EXPR && stack_items[8].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() condition := stack_items[6].Expr() pc := stack_items[8].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_s_rici_stmt := new(stmt.Stmt) move_s_rici_stmt.InitMoveSRiciStmt(suffix, dc, imm, condition, pc) stack_item := new(StackItem) stack_item.InitStmt(move_s_rici_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterMoveSRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SUFFIX && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.PAIR_REG && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COMMA && stack_items[4].StackItemType() == EXPR && stack_items[4].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() suffix := stack_items[1].Expr() dc := stack_items[2].Token() imm := stack_items[4].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.MOVE { err := errors.New("op code is not MOVE") panic(err) } move_s_ri_stmt := new(stmt.Stmt) move_s_ri_stmt.InitMoveSRiStmt(suffix, dc, imm) stack_item := new(StackItem) stack_item.InitStmt(move_s_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbIdRiiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() imm := stack_items[5].Expr() sb_id_rii_stmt := new(stmt.Stmt) sb_id_rii_stmt.InitSbIdRiiStmt(op_code, ra, off, imm) stack_item := new(StackItem) stack_item.InitStmt(sb_id_rii_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbIdRiStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() sb_id_ri_stmt := new(stmt.Stmt) sb_id_ri_stmt.InitSbIdRiStmt(op_code, ra, off) stack_item := new(StackItem) stack_item.InitStmt(sb_id_ri_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSbRirStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == EXPR && stack_items[5].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() rb := stack_items[5].Expr() sb_rir_stmt := new(stmt.Stmt) sb_rir_stmt.InitSbRirStmt(op_code, ra, off, rb) stack_item := new(StackItem) stack_item.InitStmt(sb_rir_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterSdRidStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 6 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.STORE_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.COMMA && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.COMMA && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.PAIR_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() off := stack_items[3].Expr() db := stack_items[5].Token() sd_rid_stmt := new(stmt.Stmt) sd_rid_stmt.InitSdRidStmt(op_code, ra, off, db) stack_item := new(StackItem) stack_item.InitStmt(sd_rid_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterStopStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.CI_OP_CODE { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() token_type := op_code.CiOpCodeExpr().Token().TokenType() if token_type != lexer.STOP { err := errors.New("op code is not STOP") panic(err) } stop_stmt := new(stmt.Stmt) stop_stmt.InitStopStmt() stack_item := new(StackItem) stack_item.InitStmt(stop_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterTimeCfgRStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.RR_OP_CODE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.SRC_REG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { op_code := stack_items[0].Expr() ra := stack_items[1].Expr() token_type := op_code.RrOpCodeExpr().Token().TokenType() if token_type != lexer.TIME_CFG { err := errors.New("op code is not TIME_CFG") panic(err) } time_cfg_r_stmt := new(stmt.Stmt) time_cfg_r_stmt.InitTimeCfgRStmt(ra) stack_item := new(StackItem) stack_item.InitStmt(time_cfg_r_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } func (this *Parser) RegisterLabelStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.PROGRAM_COUNTER && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.COLON { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[0].Expr() label_stmt := new(stmt.Stmt) label_stmt.InitLabelStmt(expr_) stack_item := new(StackItem) stack_item.InitStmt(label_stmt) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddStmtRule(rule) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/rule.go ================================================ package parser import ( "errors" "uPIMulator/src/device/linker/lexer" ) type Reducible func([]*StackItem) bool type Reduce func([]*StackItem) *StackItem type Rule struct { precedence map[lexer.TokenType]bool reducible Reducible reduce Reduce } func (this *Rule) Init(precedence map[lexer.TokenType]bool, reducible Reducible, reduce Reduce) { this.precedence = precedence this.reducible = reducible this.reduce = reduce } func (this *Rule) IsReducible(stack_items []*StackItem, token *lexer.Token) bool { if _, found := this.precedence[token.TokenType()]; found { return false } else { return this.reducible(stack_items) } } func (this *Rule) Reduce(stack_items []*StackItem, token *lexer.Token) *StackItem { if !this.IsReducible(stack_items, token) { err := errors.New("stack items are not reducible") panic(err) } return this.reduce(stack_items) } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stack.go ================================================ package parser import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/stmt" ) type Stack struct { stack_items []*StackItem } func (this *Stack) Init() { this.stack_items = make([]*StackItem, 0) } func (this *Stack) Push(stack_item *StackItem) { this.stack_items = append(this.stack_items, stack_item) } func (this *Stack) Pop(num int) { this.stack_items = this.stack_items[:len(this.stack_items)-num] } func (this *Stack) Front(num int) []*StackItem { stack_items := make([]*StackItem, 0) for i := 0; i < num; i++ { stack_item := this.stack_items[len(this.stack_items)-num+i] stack_items = append(stack_items, stack_item) } return stack_items } func (this *Stack) NonStmtLength() int { non_stmt_length := 0 for i := len(this.stack_items) - 1; i >= 0; i-- { stack_item := this.stack_items[i] if stack_item.StackItemType() != STMT { non_stmt_length++ } else { break } } return non_stmt_length } func (this *Stack) AreStmts() bool { for _, stack_item := range this.stack_items { if stack_item.StackItemType() == STMT { continue } else { return false } } return true } func (this *Stack) CanAccept() bool { for i, stack_item := range this.stack_items { if i < len(this.stack_items)-1 { if stack_item.StackItemType() == STMT { continue } else { return false } } else { if stack_item.StackItemType() == TOKEN && stack_item.Token().TokenType() == lexer.END_OF_FILE { return true } else { return false } } } return false } func (this *Stack) Accept() *Ast { if !this.CanAccept() { err := errors.New("stack cannot be accepted") panic(err) } stmts := make([]*stmt.Stmt, 0) for i := 0; i < len(this.stack_items)-1; i++ { stmts = append(stmts, this.stack_items[i].Stmt()) } ast := new(Ast) ast.Init(stmts) return ast } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stack_item.go ================================================ package parser import ( "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" ) type StackItemType int const ( TOKEN StackItemType = iota EXPR STMT ) type StackItem struct { stack_item_type StackItemType token *lexer.Token expr *expr.Expr stmt *stmt.Stmt } func (this *StackItem) InitToken(token *lexer.Token) { this.stack_item_type = TOKEN this.token = token } func (this *StackItem) InitExpr(expr *expr.Expr) { this.stack_item_type = EXPR this.expr = expr } func (this *StackItem) InitStmt(stmt *stmt.Stmt) { this.stack_item_type = STMT this.stmt = stmt } func (this *StackItem) StackItemType() StackItemType { return this.stack_item_type } func (this *StackItem) Token() *lexer.Token { return this.token } func (this *StackItem) Expr() *expr.Expr { return this.expr } func (this *StackItem) Stmt() *stmt.Stmt { return this.stmt } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/addrsig_stmt.go ================================================ package directive type AddrsigStmt struct { } func (this *AddrsigStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/addrsig_sym_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type AddrsigSymStmt struct { expr *expr.Expr } func (this *AddrsigSymStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *AddrsigSymStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/ascii_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" ) type AsciiStmt struct { token *lexer.Token } func (this *AsciiStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *AsciiStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/asciz_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" ) type AscizStmt struct { token *lexer.Token } func (this *AscizStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *AscizStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/byte_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ByteStmt struct { expr *expr.Expr } func (this *ByteStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ByteStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/cfi_def_cfa_offset_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CfiDefCfaOffsetStmt struct { expr *expr.Expr } func (this *CfiDefCfaOffsetStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *CfiDefCfaOffsetStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/cfi_endproc.go ================================================ package directive type CfiEndprocStmt struct { } func (this *CfiEndprocStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/cfi_offset_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CfiOffsetStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *CfiOffsetStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *CfiOffsetStmt) Expr1() *expr.Expr { return this.expr1 } func (this *CfiOffsetStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/cfi_sections_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CfiSectionsStmt struct { expr *expr.Expr } func (this *CfiSectionsStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.SECTION_NAME { err := errors.New("expr is not a section name") panic(err) } this.expr = expr_ } func (this *CfiSectionsStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/cfi_startproc_stmt.go ================================================ package directive type CfiStartprocStmt struct { } func (this *CfiStartprocStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/file_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type FileNumberStmt struct { expr *expr.Expr token1 *lexer.Token token2 *lexer.Token } func (this *FileNumberStmt) Init(expr_ *expr.Expr, token1 *lexer.Token, token2 *lexer.Token) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if token1.TokenType() != lexer.STRING { err := errors.New("token1 is not a string") panic(err) } if token2.TokenType() != lexer.STRING { err := errors.New("token2 is not a string") panic(err) } this.expr = expr_ this.token1 = token1 this.token2 = token2 } func (this *FileNumberStmt) Expr() *expr.Expr { return this.expr } func (this *FileNumberStmt) Token1() *lexer.Token { return this.token1 } func (this *FileNumberStmt) Token2() *lexer.Token { return this.token2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/file_string_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" ) type FileStringStmt struct { token *lexer.Token } func (this *FileStringStmt) Init(token *lexer.Token) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } this.token = token } func (this *FileStringStmt) Token() *lexer.Token { return this.token } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/global_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type GlobalStmt struct { expr *expr.Expr } func (this *GlobalStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *GlobalStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/loc_is_stmt_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LocIsStmtStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr expr4 *expr.Expr } func (this *LocIsStmtStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, expr4 *expr.Expr, ) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } if expr4.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr4 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 this.expr4 = expr4 } func (this *LocIsStmtStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocIsStmtStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocIsStmtStmt) Expr3() *expr.Expr { return this.expr3 } func (this *LocIsStmtStmt) Expr4() *expr.Expr { return this.expr4 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/loc_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LocNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *LocNumberStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *LocNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocNumberStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/loc_prologue_end_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LocPrologueEndStmt struct { expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *LocPrologueEndStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *LocPrologueEndStmt) Expr1() *expr.Expr { return this.expr1 } func (this *LocPrologueEndStmt) Expr2() *expr.Expr { return this.expr2 } func (this *LocPrologueEndStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/long_program_counter.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LongProgramCounterStmt struct { expr *expr.Expr } func (this *LongProgramCounterStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *LongProgramCounterStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/long_section_name_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LongSectionNameStmt struct { expr *expr.Expr } func (this *LongSectionNameStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.SECTION_NAME { err := errors.New("expr is not a section name") panic(err) } this.expr = expr_ } func (this *LongSectionNameStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/p2_align_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type P2AlignStmt struct { expr *expr.Expr } func (this *P2AlignStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *P2AlignStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/quad_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type QuadStmt struct { expr *expr.Expr } func (this *QuadStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *QuadStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/section_identifier_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SectionIdentifierNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr token *lexer.Token expr3 *expr.Expr expr4 *expr.Expr } func (this *SectionIdentifierNumberStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, expr4 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr3.ExprType() != expr.SECTION_TYPE { err := errors.New("expr3 is not a section type") panic(err) } if expr4.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr4 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.token = token this.expr3 = expr3 this.expr4 = expr4 } func (this *SectionIdentifierNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionIdentifierNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionIdentifierNumberStmt) Token() *lexer.Token { return this.token } func (this *SectionIdentifierNumberStmt) Expr3() *expr.Expr { return this.expr3 } func (this *SectionIdentifierNumberStmt) Expr4() *expr.Expr { return this.expr4 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/section_identifier_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SectionIdentifierStmt struct { expr1 *expr.Expr expr2 *expr.Expr token *lexer.Token expr3 *expr.Expr } func (this *SectionIdentifierStmt) Init( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr3.ExprType() != expr.SECTION_TYPE { err := errors.New("expr3 is not a section type") panic(err) } this.expr1 = expr1 this.expr2 = expr2 this.token = token this.expr3 = expr3 } func (this *SectionIdentifierStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionIdentifierStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionIdentifierStmt) Token() *lexer.Token { return this.token } func (this *SectionIdentifierStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/section_stack_sizes_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SectionStackSizesStmt struct { token *lexer.Token expr1 *expr.Expr expr2 *expr.Expr expr3 *expr.Expr } func (this *SectionStackSizesStmt) Init( token *lexer.Token, expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, ) { if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr1.ExprType() != expr.SECTION_TYPE { err := errors.New("expr1 is not a section type") panic(err) } if expr2.ExprType() != expr.SECTION_NAME { err := errors.New("expr2 is not a section name") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.token = token this.expr1 = expr1 this.expr2 = expr2 this.expr3 = expr3 } func (this *SectionStackSizesStmt) Token() *lexer.Token { return this.token } func (this *SectionStackSizesStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStackSizesStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionStackSizesStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/section_string_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SectionStringNumberStmt struct { expr1 *expr.Expr token *lexer.Token expr2 *expr.Expr expr3 *expr.Expr } func (this *SectionStringNumberStmt) Init( expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr, expr3 *expr.Expr, ) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr2.ExprType() != expr.SECTION_TYPE { err := errors.New("expr2 is not a section type") panic(err) } if expr3.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr3 is not a program counter") panic(err) } this.expr1 = expr1 this.token = token this.expr2 = expr2 this.expr3 = expr3 } func (this *SectionStringNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStringNumberStmt) Token() *lexer.Token { return this.token } func (this *SectionStringNumberStmt) Expr2() *expr.Expr { return this.expr2 } func (this *SectionStringNumberStmt) Expr3() *expr.Expr { return this.expr3 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/section_string_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SectionStringStmt struct { expr1 *expr.Expr token *lexer.Token expr2 *expr.Expr } func (this *SectionStringStmt) Init(expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr) { if expr1.ExprType() != expr.SECTION_NAME { err := errors.New("expr1 is not a section name") panic(err) } if token.TokenType() != lexer.STRING { err := errors.New("token is not a string") panic(err) } if expr2.ExprType() != expr.SECTION_TYPE { err := errors.New("expr2 is not a section type") panic(err) } this.expr1 = expr1 this.token = token this.expr2 = expr2 } func (this *SectionStringStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SectionStringStmt) Token() *lexer.Token { return this.token } func (this *SectionStringStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/set_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type SetStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *SetStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr1 is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr2 is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *SetStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SetStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/short_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ShortStmt struct { expr *expr.Expr } func (this *ShortStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ShortStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/size_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type SizeStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *SizeStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *SizeStmt) Expr1() *expr.Expr { return this.expr1 } func (this *SizeStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/text_stmt.go ================================================ package directive type TextStmt struct { } func (this *TextStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/type_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type TypeStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *TypeStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.SYMBOL_TYPE { err := errors.New("expr is not a symbol type") panic(err) } this.expr1 = expr2 } func (this *TypeStmt) Expr1() *expr.Expr { return this.expr1 } func (this *TypeStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/weak_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type WeakStmt struct { expr *expr.Expr } func (this *WeakStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *WeakStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/zero_double_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ZeroDoubleNumberStmt struct { expr1 *expr.Expr expr2 *expr.Expr } func (this *ZeroDoubleNumberStmt) Init(expr1 *expr.Expr, expr2 *expr.Expr) { if expr1.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } if expr2.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr1 = expr1 this.expr2 = expr2 } func (this *ZeroDoubleNumberStmt) Expr1() *expr.Expr { return this.expr1 } func (this *ZeroDoubleNumberStmt) Expr2() *expr.Expr { return this.expr2 } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/directive/zero_single_number_stmt.go ================================================ package directive import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ZeroSingleNumberStmt struct { expr *expr.Expr } func (this *ZeroSingleNumberStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr is not a program counter") panic(err) } this.expr = expr_ } func (this *ZeroSingleNumberStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/ci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CiStmt struct { op_code *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *CiStmt) Init(op_code *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.CI_OP_CODE { err := errors.New("op code is not a CI op code") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.condition = condition this.pc = pc } func (this *CiStmt) OpCode() *expr.Expr { return this.op_code } func (this *CiStmt) Condition() *expr.Expr { return this.condition } func (this *CiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/ddci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type DdciStmt struct { op_code *expr.Expr dc *lexer.Token db *lexer.Token condition *expr.Expr pc *expr.Expr } func (this *DdciStmt) Init( op_code *expr.Expr, dc *lexer.Token, db *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.DDCI_OP_CODE { err := errors.New("op code is not a DDCI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.db = db this.condition = condition this.pc = pc } func (this *DdciStmt) OpCode() *expr.Expr { return this.op_code } func (this *DdciStmt) Dc() *lexer.Token { return this.dc } func (this *DdciStmt) Db() *lexer.Token { return this.db } func (this *DdciStmt) Condition() *expr.Expr { return this.condition } func (this *DdciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/dma_rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type DmaRriStmt struct { op_code *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *DmaRriStmt) Init(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.DMA_RRI_OP_CODE { err := errors.New("op code is not a DMA_RRI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.rb = rb this.imm = imm } func (this *DmaRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *DmaRriStmt) Ra() *expr.Expr { return this.ra } func (this *DmaRriStmt) Rb() *expr.Expr { return this.rb } func (this *DmaRriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/drdici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type DrdiciStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr db *lexer.Token imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *DrdiciStmt) Init( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.DRDICI_OP_CODE { err := errors.New("op code is not a DRDICI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.db = db this.imm = imm this.condition = condition this.pc = pc } func (this *DrdiciStmt) OpCode() *expr.Expr { return this.op_code } func (this *DrdiciStmt) Dc() *lexer.Token { return this.dc } func (this *DrdiciStmt) Ra() *expr.Expr { return this.ra } func (this *DrdiciStmt) Db() *lexer.Token { return this.db } func (this *DrdiciStmt) Imm() *expr.Expr { return this.imm } func (this *DrdiciStmt) Condition() *expr.Expr { return this.condition } func (this *DrdiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/edri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type EdriStmt struct { op_code *expr.Expr endian *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *EdriStmt) Init( op_code *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.dc = dc this.ra = ra this.off = off } func (this *EdriStmt) OpCode() *expr.Expr { return this.op_code } func (this *EdriStmt) Endian() *expr.Expr { return this.endian } func (this *EdriStmt) Dc() *lexer.Token { return this.dc } func (this *EdriStmt) Ra() *expr.Expr { return this.ra } func (this *EdriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/erid_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type EridStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr db *lexer.Token } func (this *EridStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.db = db } func (this *EridStmt) OpCode() *expr.Expr { return this.op_code } func (this *EridStmt) Endian() *expr.Expr { return this.endian } func (this *EridStmt) Ra() *expr.Expr { return this.ra } func (this *EridStmt) Off() *expr.Expr { return this.off } func (this *EridStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/erii_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type EriiStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr imm *expr.Expr } func (this *EriiStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.imm = imm } func (this *EriiStmt) OpCode() *expr.Expr { return this.op_code } func (this *EriiStmt) Endian() *expr.Expr { return this.endian } func (this *EriiStmt) Ra() *expr.Expr { return this.ra } func (this *EriiStmt) Off() *expr.Expr { return this.off } func (this *EriiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/erir_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ErirStmt struct { op_code *expr.Expr endian *expr.Expr ra *expr.Expr off *expr.Expr rb *expr.Expr } func (this *ErirStmt) Init( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr, ) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.ra = ra this.off = off this.rb = rb } func (this *ErirStmt) OpCode() *expr.Expr { return this.op_code } func (this *ErirStmt) Endian() *expr.Expr { return this.endian } func (this *ErirStmt) Ra() *expr.Expr { return this.ra } func (this *ErirStmt) Off() *expr.Expr { return this.off } func (this *ErirStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/erri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type ErriStmt struct { op_code *expr.Expr endian *expr.Expr rc *expr.Expr ra *expr.Expr off *expr.Expr } func (this *ErriStmt) Init( op_code *expr.Expr, endian *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.endian = endian this.rc = rc this.ra = ra this.off = off } func (this *ErriStmt) OpCode() *expr.Expr { return this.op_code } func (this *ErriStmt) Endian() *expr.Expr { return this.endian } func (this *ErriStmt) Rc() *expr.Expr { return this.rc } func (this *ErriStmt) Ra() *expr.Expr { return this.ra } func (this *ErriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/i_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type IStmt struct { op_code *expr.Expr imm *expr.Expr } func (this *IStmt) Init(op_code *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.I_OP_CODE { err := errors.New("op code is not an I op code") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.imm = imm } func (this *IStmt) OpCode() *expr.Expr { return this.op_code } func (this *IStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/nop_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type NopStmt struct { op_code *expr.Expr } func (this *NopStmt) Init(op_code *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } this.op_code = op_code } func (this *NopStmt) OpCode() *expr.Expr { return this.op_code } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/r_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RStmt struct { op_code *expr.Expr rc *expr.Expr } func (this *RStmt) Init(op_code *expr.Expr, rc *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } this.op_code = op_code this.rc = rc } func (this *RStmt) OpCode() *expr.Expr { return this.op_code } func (this *RStmt) Rc() *expr.Expr { return this.rc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RciStmt struct { op_code *expr.Expr rc *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RciStmt) Init(op_code *expr.Expr, rc *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.condition = condition this.pc = pc } func (this *RciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RciStmt) Rc() *expr.Expr { return this.rc } func (this *RciStmt) Condition() *expr.Expr { return this.condition } func (this *RciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RiciStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RiciStmt) Init( op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RICI_OP_CODE { err := errors.New("op code is not an RICI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *RiciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RiciStmt) Ra() *expr.Expr { return this.ra } func (this *RiciStmt) Imm() *expr.Expr { return this.imm } func (this *RiciStmt) Condition() *expr.Expr { return this.condition } func (this *RiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rir_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RirStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr } func (this *RirStmt) Init(op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra } func (this *RirStmt) OpCode() *expr.Expr { return this.op_code } func (this *RirStmt) Rc() *expr.Expr { return this.rc } func (this *RirStmt) Imm() *expr.Expr { return this.imm } func (this *RirStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rirc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RircStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *RircStmt) Init( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra this.condition = condition } func (this *RircStmt) OpCode() *expr.Expr { return this.op_code } func (this *RircStmt) Rc() *expr.Expr { return this.rc } func (this *RircStmt) Imm() *expr.Expr { return this.imm } func (this *RircStmt) Ra() *expr.Expr { return this.ra } func (this *RircStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rirci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RirciStmt struct { op_code *expr.Expr rc *expr.Expr imm *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RirciStmt) Init( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.imm = imm this.ra = ra this.condition = condition this.pc = pc } func (this *RirciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RirciStmt) Rc() *expr.Expr { return this.rc } func (this *RirciStmt) Imm() *expr.Expr { return this.imm } func (this *RirciStmt) Ra() *expr.Expr { return this.ra } func (this *RirciStmt) Condition() *expr.Expr { return this.condition } func (this *RirciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr } func (this *RrStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra } func (this *RrStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrStmt) Rc() *expr.Expr { return this.rc } func (this *RrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrcStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *RrcStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.condition = condition } func (this *RrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrcStmt) Rc() *expr.Expr { return this.rc } func (this *RrcStmt) Ra() *expr.Expr { return this.ra } func (this *RrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.condition = condition this.pc = pc } func (this *RrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrciStmt) Rc() *expr.Expr { return this.rc } func (this *RrciStmt) Ra() *expr.Expr { return this.ra } func (this *RrciStmt) Condition() *expr.Expr { return this.condition } func (this *RrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr } func (this *RriStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm } func (this *RriStmt) OpCode() *expr.Expr { return this.op_code } func (this *RriStmt) Rc() *expr.Expr { return this.rc } func (this *RriStmt) Ra() *expr.Expr { return this.ra } func (this *RriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rric_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RricStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr } func (this *RricStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm this.condition = condition } func (this *RricStmt) OpCode() *expr.Expr { return this.op_code } func (this *RricStmt) Rc() *expr.Expr { return this.rc } func (this *RricStmt) Ra() *expr.Expr { return this.ra } func (this *RricStmt) Imm() *expr.Expr { return this.imm } func (this *RricStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RriciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RriciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *RriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RriciStmt) Rc() *expr.Expr { return this.rc } func (this *RriciStmt) Ra() *expr.Expr { return this.ra } func (this *RriciStmt) Imm() *expr.Expr { return this.imm } func (this *RriciStmt) Condition() *expr.Expr { return this.condition } func (this *RriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrrStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr } func (this *RrrStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb } func (this *RrrStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrStmt) Rc() *expr.Expr { return this.rc } func (this *RrrStmt) Ra() *expr.Expr { return this.ra } func (this *RrrStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrrcStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr condition *expr.Expr } func (this *RrrcStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.condition = condition } func (this *RrrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrcStmt) Rc() *expr.Expr { return this.rc } func (this *RrrcStmt) Ra() *expr.Expr { return this.ra } func (this *RrrcStmt) Rb() *expr.Expr { return this.rb } func (this *RrrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrrciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrrciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.condition = condition this.pc = pc } func (this *RrrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrrciStmt) Rc() *expr.Expr { return this.rc } func (this *RrrciStmt) Ra() *expr.Expr { return this.ra } func (this *RrrciStmt) Rb() *expr.Expr { return this.rb } func (this *RrrciStmt) Condition() *expr.Expr { return this.condition } func (this *RrrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *RrriStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.imm = imm } func (this *RrriStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrriStmt) Rc() *expr.Expr { return this.rc } func (this *RrriStmt) Ra() *expr.Expr { return this.ra } func (this *RrriStmt) Rb() *expr.Expr { return this.rb } func (this *RrriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/rrrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type RrriciStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr rb *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *RrriciStmt) Init( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a progrcm counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.rb = rb this.imm = imm this.condition = condition this.pc = pc } func (this *RrriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *RrriciStmt) Rc() *expr.Expr { return this.rc } func (this *RrriciStmt) Ra() *expr.Expr { return this.ra } func (this *RrriciStmt) Rb() *expr.Expr { return this.rb } func (this *RrriciStmt) Imm() *expr.Expr { return this.imm } func (this *RrriciStmt) Condition() *expr.Expr { return this.condition } func (this *RrriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_erri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SErriStmt struct { op_code *expr.Expr suffix *expr.Expr endian *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *SErriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if endian.ExprType() != expr.ENDIAN { err := errors.New("endian is not an endian") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.endian = endian this.dc = dc this.ra = ra this.off = off } func (this *SErriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SErriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SErriStmt) Endian() *expr.Expr { return this.endian } func (this *SErriStmt) Dc() *lexer.Token { return this.dc } func (this *SErriStmt) Ra() *expr.Expr { return this.ra } func (this *SErriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_r_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token } func (this *SRStmt) Init(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc } func (this *SRStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRStmt) Dc() *lexer.Token { return this.dc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token condition *expr.Expr pc *expr.Expr } func (this *SRciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.R_OP_CODE { err := errors.New("op code is not an R op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.condition = condition this.pc = pc } func (this *SRciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRciStmt) Dc() *lexer.Token { return this.dc } func (this *SRciStmt) Condition() *expr.Expr { return this.condition } func (this *SRciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rirc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRircStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token imm *expr.Expr ra *expr.Expr condition *expr.Expr } func (this *SRircStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = imm this.ra = ra this.condition = condition } func (this *SRircStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRircStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRircStmt) Dc() *lexer.Token { return this.dc } func (this *SRircStmt) Imm() *expr.Expr { return this.imm } func (this *SRircStmt) Ra() *expr.Expr { return this.ra } func (this *SRircStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rirci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRirciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token imm *expr.Expr ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRirciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.imm = imm this.ra = ra this.condition = condition this.pc = pc } func (this *SRirciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRirciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRirciStmt) Dc() *lexer.Token { return this.dc } func (this *SRirciStmt) Imm() *expr.Expr { return this.imm } func (this *SRirciStmt) Ra() *expr.Expr { return this.ra } func (this *SRirciStmt) Condition() *expr.Expr { return this.condition } func (this *SRirciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr } func (this *SRrStmt) Init(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra } func (this *SRrStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrStmt) Dc() *lexer.Token { return this.dc } func (this *SRrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrcStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr condition *expr.Expr } func (this *SRrcStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.condition = condition } func (this *SRrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrcStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrcStmt) Dc() *lexer.Token { return this.dc } func (this *SRrcStmt) Ra() *expr.Expr { return this.ra } func (this *SRrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RR_OP_CODE { err := errors.New("op code is not an RR op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.condition = condition this.pc = pc } func (this *SRrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr } func (this *SRriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm } func (this *SRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRriStmt) Dc() *lexer.Token { return this.dc } func (this *SRriStmt) Ra() *expr.Expr { return this.ra } func (this *SRriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rric_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRricStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr condition *expr.Expr } func (this *SRricStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm this.condition = condition } func (this *SRricStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRricStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRricStmt) Dc() *lexer.Token { return this.dc } func (this *SRricStmt) Ra() *expr.Expr { return this.ra } func (this *SRricStmt) Imm() *expr.Expr { return this.imm } func (this *SRricStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRriciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRriciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.imm = imm this.condition = condition this.pc = pc } func (this *SRriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRriciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRriciStmt) Dc() *lexer.Token { return this.dc } func (this *SRriciStmt) Ra() *expr.Expr { return this.ra } func (this *SRriciStmt) Imm() *expr.Expr { return this.imm } func (this *SRriciStmt) Condition() *expr.Expr { return this.condition } func (this *SRriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrr_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrrStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr } func (this *SRrrStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb } func (this *SRrrStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrrc_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrrcStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr condition *expr.Expr } func (this *SRrrcStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.condition = condition } func (this *SRrrcStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrcStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrcStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrcStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrcStmt) Rb() *expr.Expr { return this.rb } func (this *SRrrcStmt) Condition() *expr.Expr { return this.condition } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrrci_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrrciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrrciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRI_OP_CODE { err := errors.New("op code is not an RRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.condition = condition this.pc = pc } func (this *SRrrciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrrciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrrciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrrciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrrciStmt) Rb() *expr.Expr { return this.rb } func (this *SRrrciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrrciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrri_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr imm *expr.Expr } func (this *SRrriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = imm } func (this *SRrriStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrriStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrriStmt) Dc() *lexer.Token { return this.dc } func (this *SRrriStmt) Ra() *expr.Expr { return this.ra } func (this *SRrriStmt) Rb() *expr.Expr { return this.rb } func (this *SRrriStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/instruction/s_rrrici_stmt.go ================================================ package instruction import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SRrriciStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr rb *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *SRrriciStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if op_code.ExprType() != expr.RRRI_OP_CODE { err := errors.New("op code is not an RRRI op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.rb = rb this.imm = imm this.condition = condition this.pc = pc } func (this *SRrriciStmt) OpCode() *expr.Expr { return this.op_code } func (this *SRrriciStmt) Suffix() *expr.Expr { return this.suffix } func (this *SRrriciStmt) Dc() *lexer.Token { return this.dc } func (this *SRrriciStmt) Ra() *expr.Expr { return this.ra } func (this *SRrriciStmt) Rb() *expr.Expr { return this.rb } func (this *SRrriciStmt) Imm() *expr.Expr { return this.imm } func (this *SRrriciStmt) Condition() *expr.Expr { return this.condition } func (this *SRrriciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/label_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LabelStmt struct { expr *expr.Expr } func (this *LabelStmt) Init(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.expr = expr_ } func (this *LabelStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/stmt.go ================================================ package stmt import ( "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt/directive" "uPIMulator/src/device/linker/parser/stmt/instruction" "uPIMulator/src/device/linker/parser/stmt/sugar" ) type StmtType int const ( ADDRSIG StmtType = iota ADDRSIG_SYM ASCII ASCIZ BYTE CFI_DEF_CFA_OFFSET CFI_ENDPROC CFI_OFFSET CFI_SECTIONS CFI_STARTPROC FILE_NUMBER FILE_STRING GLOBAL LOC_IS_STMT LOC_NUMBER LOC_PROLOGUE_END LONG_PROGRAM_COUNTER LONG_SECTION_NAME P2_ALIGN QUAD SECTION_IDENTIFIER_NUMBER SECTION_IDENTIFIER SECTION_STACK_SIZES SECTION_STRING_NUMBER SECTION_STRING SET SHORT SIZE TEXT TYPE WEAK ZERO_SINGLE_NUMBER ZERO_DOUBLE_NUMBER RICI RRI RRIC RRICI RRR RRRC RRRCI S_RRI S_RRIC S_RRICI S_RRR S_RRRC S_RRRCI RR RRC RRCI S_RR S_RRC S_RRCI DRDICI RRRI RRRICI S_RRRI S_RRRICI RIR RIRC RIRCI S_RIRC S_RIRCI R RCI S_R S_RCI CI I DDCI ERRI EDRI S_ERRI ERII ERIR ERID DMA_RRI NOP MOVE_RI MOVE_RICI MOVE_S_RI MOVE_S_RICI JEQ_RII JEQ_RRI JNZ_RI JUMP_I JUMP_R DIV_STEP_DRDI BOOT_RI STOP CALL_RI CALL_RR BKP MOVD_DD TIME_CFG_R LBS_RRI LBS_S_RRI LD_DRI SB_RIR SB_ID_RII SB_ID_RI SD_RID LABEL ) type Stmt struct { stmt_type StmtType addrsig_stmt *directive.AddrsigStmt addrsig_sym_stmt *directive.AddrsigSymStmt ascii_stmt *directive.AsciiStmt asciz_stmt *directive.AscizStmt byte_stmt *directive.ByteStmt cfi_def_cfa_offset_stmt *directive.CfiDefCfaOffsetStmt cfi_endproc_stmt *directive.CfiEndprocStmt cfi_offset_stmt *directive.CfiOffsetStmt cfi_sections_stmt *directive.CfiSectionsStmt cfi_startproc_stmt *directive.CfiStartprocStmt file_number_stmt *directive.FileNumberStmt file_string_stmt *directive.FileStringStmt global_stmt *directive.GlobalStmt loc_is_stmt_stmt *directive.LocIsStmtStmt loc_number_stmt *directive.LocNumberStmt loc_prologue_end_stmt *directive.LocPrologueEndStmt long_program_counter_stmt *directive.LongProgramCounterStmt long_section_name_stmt *directive.LongSectionNameStmt p2_align_stmt *directive.P2AlignStmt quad_stmt *directive.QuadStmt section_identifier_number_stmt *directive.SectionIdentifierNumberStmt section_identifier_stmt *directive.SectionIdentifierStmt section_stack_sizes_stmt *directive.SectionStackSizesStmt section_string_number_stmt *directive.SectionStringNumberStmt section_string_stmt *directive.SectionStringStmt set_stmt *directive.SetStmt short_stmt *directive.ShortStmt size_stmt *directive.SizeStmt text_stmt *directive.TextStmt type_stmt *directive.TypeStmt weak_stmt *directive.WeakStmt zero_single_number_stmt *directive.ZeroSingleNumberStmt zero_double_number_stmt *directive.ZeroDoubleNumberStmt ci_stmt *instruction.CiStmt ddci_stmt *instruction.DdciStmt dma_rri_stmt *instruction.DmaRriStmt drdici_stmt *instruction.DrdiciStmt edri_stmt *instruction.EdriStmt erid_stmt *instruction.EridStmt erii_stmt *instruction.EriiStmt erir_stmt *instruction.ErirStmt erri_stmt *instruction.ErriStmt i_stmt *instruction.IStmt nop_stmt *instruction.NopStmt r_stmt *instruction.RStmt rci_stmt *instruction.RciStmt rici_stmt *instruction.RiciStmt rir_stmt *instruction.RirStmt rirc_stmt *instruction.RircStmt rirci_stmt *instruction.RirciStmt rr_stmt *instruction.RrStmt rrc_stmt *instruction.RrcStmt rrci_stmt *instruction.RrciStmt rri_stmt *instruction.RriStmt rric_stmt *instruction.RricStmt rrici_stmt *instruction.RriciStmt rrr_stmt *instruction.RrrStmt rrrc_stmt *instruction.RrrcStmt rrrci_stmt *instruction.RrrciStmt rrri_stmt *instruction.RrriStmt rrrici_stmt *instruction.RrriciStmt s_erri_stmt *instruction.SErriStmt s_r_stmt *instruction.SRStmt s_rci_stmt *instruction.SRciStmt s_rirc_stmt *instruction.SRircStmt s_rirci_stmt *instruction.SRirciStmt s_rr_stmt *instruction.SRrStmt s_rrc_stmt *instruction.SRrcStmt s_rrci_stmt *instruction.SRrciStmt s_rri_stmt *instruction.SRriStmt s_rric_stmt *instruction.SRricStmt s_rrici_stmt *instruction.SRriciStmt s_rrr_stmt *instruction.SRrrStmt s_rrrc_stmt *instruction.SRrrcStmt s_rrrci_stmt *instruction.SRrrciStmt s_rrri_stmt *instruction.SRrriStmt s_rrrici_stmt *instruction.SRrriciStmt bkp_stmt *sugar.BkpStmt boot_ri_stmt *sugar.BootRiStmt call_ri_stmt *sugar.CallRiStmt call_rr_stmt *sugar.CallRrStmt div_step_drdi_stmt *sugar.DivStepDrdiStmt jeq_rii_stmt *sugar.JeqRiiStmt jeq_rri_stmt *sugar.JeqRriStmt jnz_ri_stmt *sugar.JnzRiStmt jump_i_stmt *sugar.JumpIStmt jump_r_stmt *sugar.JumpRStmt lbs_rri_stmt *sugar.LbsRriStmt lbs_s_rri_stmt *sugar.LbsSRriStmt ld_dri_stmt *sugar.LdDriStmt movd_dd_stmt *sugar.MovdDdStmt move_ri_stmt *sugar.MoveRiStmt move_rici_stmt *sugar.MoveRiciStmt move_s_ri_stmt *sugar.MoveSRiStmt move_s_rici_stmt *sugar.MoveSRiciStmt sb_id_ri_stmt *sugar.SbIdRiStmt sb_id_rii_stmt *sugar.SbIdRiiStmt sb_rir_stmt *sugar.SbRirStmt sd_rid_stmt *sugar.SdRidStmt stop_stmt *sugar.StopStmt time_cfg_r_stmt *sugar.TimeCfgRStmt label_stmt *LabelStmt } func (this *Stmt) InitAddrsigStmt() { this.stmt_type = ADDRSIG this.addrsig_stmt = new(directive.AddrsigStmt) this.addrsig_stmt.Init() } func (this *Stmt) InitAddrsigSymStmt(expr_ *expr.Expr) { this.stmt_type = ADDRSIG_SYM this.addrsig_sym_stmt = new(directive.AddrsigSymStmt) this.addrsig_sym_stmt.Init(expr_) } func (this *Stmt) InitAsciiStmt(token *lexer.Token) { this.stmt_type = ASCII this.ascii_stmt = new(directive.AsciiStmt) this.ascii_stmt.Init(token) } func (this *Stmt) InitAscizStmt(token *lexer.Token) { this.stmt_type = ASCIZ this.asciz_stmt = new(directive.AscizStmt) this.asciz_stmt.Init(token) } func (this *Stmt) InitByteStmt(expr_ *expr.Expr) { this.stmt_type = BYTE this.byte_stmt = new(directive.ByteStmt) this.byte_stmt.Init(expr_) } func (this *Stmt) InitCfiDefCfaOffsetStmt(expr_ *expr.Expr) { this.stmt_type = CFI_DEF_CFA_OFFSET this.cfi_def_cfa_offset_stmt = new(directive.CfiDefCfaOffsetStmt) this.cfi_def_cfa_offset_stmt.Init(expr_) } func (this *Stmt) InitCfiEndprocStmt() { this.stmt_type = CFI_ENDPROC this.cfi_endproc_stmt = new(directive.CfiEndprocStmt) this.cfi_endproc_stmt.Init() } func (this *Stmt) InitCfiOffsetStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = CFI_OFFSET this.cfi_offset_stmt = new(directive.CfiOffsetStmt) this.cfi_offset_stmt.Init(expr1, expr2) } func (this *Stmt) InitCfiSectionsStmt(expr_ *expr.Expr) { this.stmt_type = CFI_SECTIONS this.cfi_sections_stmt = new(directive.CfiSectionsStmt) this.cfi_sections_stmt.Init(expr_) } func (this *Stmt) InitCfiStartprocStmt() { this.stmt_type = CFI_STARTPROC this.cfi_startproc_stmt = new(directive.CfiStartprocStmt) this.cfi_startproc_stmt.Init() } func (this *Stmt) InitFileNumberStmt(expr_ *expr.Expr, token1 *lexer.Token, token2 *lexer.Token) { this.stmt_type = FILE_NUMBER this.file_number_stmt = new(directive.FileNumberStmt) this.file_number_stmt.Init(expr_, token1, token2) } func (this *Stmt) InitFileStringStmt(token *lexer.Token) { this.stmt_type = FILE_STRING this.file_string_stmt = new(directive.FileStringStmt) this.file_string_stmt.Init(token) } func (this *Stmt) InitGlobalStmt(expr_ *expr.Expr) { this.stmt_type = GLOBAL this.global_stmt = new(directive.GlobalStmt) this.global_stmt.Init(expr_) } func (this *Stmt) InitLocIsStmtStmt( expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, expr4 *expr.Expr, ) { this.stmt_type = LOC_IS_STMT this.loc_is_stmt_stmt = new(directive.LocIsStmtStmt) this.loc_is_stmt_stmt.Init(expr1, expr2, expr3, expr4) } func (this *Stmt) InitLocNumberStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = LOC_NUMBER this.loc_number_stmt = new(directive.LocNumberStmt) this.loc_number_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitLocPrologueEndStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = LOC_PROLOGUE_END this.loc_prologue_end_stmt = new(directive.LocPrologueEndStmt) this.loc_prologue_end_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitLongProgramCounterStmt(expr_ *expr.Expr) { this.stmt_type = LONG_PROGRAM_COUNTER this.long_program_counter_stmt = new(directive.LongProgramCounterStmt) this.long_program_counter_stmt.Init(expr_) } func (this *Stmt) InitLongSectionNameStmt(expr_ *expr.Expr) { this.stmt_type = LONG_SECTION_NAME this.long_section_name_stmt = new(directive.LongSectionNameStmt) this.long_section_name_stmt.Init(expr_) } func (this *Stmt) InitP2AlignStmt(expr_ *expr.Expr) { this.stmt_type = P2_ALIGN this.p2_align_stmt = new(directive.P2AlignStmt) this.p2_align_stmt.Init(expr_) } func (this *Stmt) InitQuadStmt(expr_ *expr.Expr) { this.stmt_type = QUAD this.quad_stmt = new(directive.QuadStmt) this.quad_stmt.Init(expr_) } func (this *Stmt) InitSectionIdentifierNumberStmt( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, expr4 *expr.Expr, ) { this.stmt_type = SECTION_IDENTIFIER_NUMBER this.section_identifier_number_stmt = new(directive.SectionIdentifierNumberStmt) this.section_identifier_number_stmt.Init(expr1, expr2, token, expr3, expr4) } func (this *Stmt) InitSectionIdentifierStmt( expr1 *expr.Expr, expr2 *expr.Expr, token *lexer.Token, expr3 *expr.Expr, ) { this.stmt_type = SECTION_IDENTIFIER this.section_identifier_stmt = new(directive.SectionIdentifierStmt) this.section_identifier_stmt.Init(expr1, expr2, token, expr3) } func (this *Stmt) InitSectionStackSizesStmt( token *lexer.Token, expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr, ) { this.stmt_type = SECTION_STACK_SIZES this.section_stack_sizes_stmt = new(directive.SectionStackSizesStmt) this.section_stack_sizes_stmt.Init(token, expr1, expr2, expr3) } func (this *Stmt) InitSectionStringNumberStmt( expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr, expr3 *expr.Expr, ) { this.stmt_type = SECTION_STRING_NUMBER this.section_string_number_stmt = new(directive.SectionStringNumberStmt) this.section_string_number_stmt.Init(expr1, token, expr2, expr3) } func (this *Stmt) InitSectionStringStmt(expr1 *expr.Expr, token *lexer.Token, expr2 *expr.Expr) { this.stmt_type = SECTION_STRING this.section_string_stmt = new(directive.SectionStringStmt) this.section_string_stmt.Init(expr1, token, expr2) } func (this *Stmt) InitSetStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = SET this.set_stmt = new(directive.SetStmt) this.set_stmt.Init(expr1, expr2) } func (this *Stmt) InitShortStmt(expr_ *expr.Expr) { this.stmt_type = SHORT this.short_stmt = new(directive.ShortStmt) this.short_stmt.Init(expr_) } func (this *Stmt) InitSizeStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = SIZE this.size_stmt = new(directive.SizeStmt) this.size_stmt.Init(expr1, expr2) } func (this *Stmt) InitTextStmt() { this.stmt_type = TEXT this.text_stmt = new(directive.TextStmt) this.text_stmt.Init() } func (this *Stmt) InitTypeStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = TYPE this.type_stmt = new(directive.TypeStmt) this.type_stmt.Init(expr1, expr2) } func (this *Stmt) InitWeakStmt(expr_ *expr.Expr) { this.stmt_type = WEAK this.weak_stmt = new(directive.WeakStmt) this.weak_stmt.Init(expr_) } func (this *Stmt) InitZeroSingleNumberStmt(expr_ *expr.Expr) { this.stmt_type = ZERO_SINGLE_NUMBER this.zero_single_number_stmt = new(directive.ZeroSingleNumberStmt) this.zero_single_number_stmt.Init(expr_) } func (this *Stmt) InitZeroDoubleNumberStmt(expr1 *expr.Expr, expr2 *expr.Expr) { this.stmt_type = ZERO_DOUBLE_NUMBER this.zero_double_number_stmt = new(directive.ZeroDoubleNumberStmt) this.zero_double_number_stmt.Init(expr1, expr2) } func (this *Stmt) InitCiStmt(expr1 *expr.Expr, expr2 *expr.Expr, expr3 *expr.Expr) { this.stmt_type = CI this.ci_stmt = new(instruction.CiStmt) this.ci_stmt.Init(expr1, expr2, expr3) } func (this *Stmt) InitDdciStmt( op_code *expr.Expr, dc *lexer.Token, db *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = DDCI this.ddci_stmt = new(instruction.DdciStmt) this.ddci_stmt.Init(op_code, dc, db, condition, pc) } func (this *Stmt) InitDmaRriStmt(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr) { this.stmt_type = DMA_RRI this.dma_rri_stmt = new(instruction.DmaRriStmt) this.dma_rri_stmt.Init(op_code, ra, rb, imm) } func (this *Stmt) InitDrdiciStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = DRDICI this.drdici_stmt = new(instruction.DrdiciStmt) this.drdici_stmt.Init(op_code, dc, ra, db, imm, condition, pc) } func (this *Stmt) InitEdriStmt( op_code *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = EDRI this.edri_stmt = new(instruction.EdriStmt) this.edri_stmt.Init(op_code, endian, dc, ra, off) } func (this *Stmt) InitEridStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { this.stmt_type = ERID this.erid_stmt = new(instruction.EridStmt) this.erid_stmt.Init(op_code, endian, ra, off, db) } func (this *Stmt) InitEriiStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { this.stmt_type = ERII this.erii_stmt = new(instruction.EriiStmt) this.erii_stmt.Init(op_code, endian, ra, off, imm) } func (this *Stmt) InitErirStmt( op_code *expr.Expr, endian *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr, ) { this.stmt_type = ERIR this.erir_stmt = new(instruction.ErirStmt) this.erir_stmt.Init(op_code, endian, ra, off, rb) } func (this *Stmt) InitErriStmt( op_code *expr.Expr, endian *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = ERRI this.erri_stmt = new(instruction.ErriStmt) this.erri_stmt.Init(op_code, endian, rc, ra, off) } func (this *Stmt) InitIStmt(op_code *expr.Expr, imm *expr.Expr) { this.stmt_type = I this.i_stmt = new(instruction.IStmt) this.i_stmt.Init(op_code, imm) } func (this *Stmt) InitNopStmt(op_code *expr.Expr) { this.stmt_type = NOP this.nop_stmt = new(instruction.NopStmt) this.nop_stmt.Init(op_code) } func (this *Stmt) InitRStmt(op_code *expr.Expr, rc *expr.Expr) { this.stmt_type = R this.r_stmt = new(instruction.RStmt) this.r_stmt.Init(op_code, rc) } func (this *Stmt) InitRciStmt( op_code *expr.Expr, rc *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RCI this.rci_stmt = new(instruction.RciStmt) this.rci_stmt.Init(op_code, rc, condition, pc) } func (this *Stmt) InitRiciStmt( op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RICI this.rici_stmt = new(instruction.RiciStmt) this.rici_stmt.Init(op_code, ra, imm, condition, pc) } func (this *Stmt) InitRirStmt(op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr) { this.stmt_type = RIR this.rir_stmt = new(instruction.RirStmt) this.rir_stmt.Init(op_code, rc, imm, ra) } func (this *Stmt) InitRircStmt( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RIRC this.rirc_stmt = new(instruction.RircStmt) this.rirc_stmt.Init(op_code, rc, imm, ra, condition) } func (this *Stmt) InitRirciStmt( op_code *expr.Expr, rc *expr.Expr, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RIRCI this.rirci_stmt = new(instruction.RirciStmt) this.rirci_stmt.Init(op_code, rc, imm, ra, condition, pc) } func (this *Stmt) InitRrStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr) { this.stmt_type = RR this.rr_stmt = new(instruction.RrStmt) this.rr_stmt.Init(op_code, rc, ra) } func (this *Stmt) InitRrcStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRC this.rrc_stmt = new(instruction.RrcStmt) this.rrc_stmt.Init(op_code, rc, ra, condition) } func (this *Stmt) InitRrciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRCI this.rrci_stmt = new(instruction.RrciStmt) this.rrci_stmt.Init(op_code, rc, ra, condition, pc) } func (this *Stmt) InitRriStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr) { this.stmt_type = RRI this.rri_stmt = new(instruction.RriStmt) this.rri_stmt.Init(op_code, rc, ra, imm) } func (this *Stmt) InitRricStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRIC this.rric_stmt = new(instruction.RricStmt) this.rric_stmt.Init(op_code, rc, ra, imm, condition) } func (this *Stmt) InitRriciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRICI this.rrici_stmt = new(instruction.RriciStmt) this.rrici_stmt.Init(op_code, rc, ra, imm, condition, pc) } func (this *Stmt) InitRrrStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr) { this.stmt_type = RRR this.rrr_stmt = new(instruction.RrrStmt) this.rrr_stmt.Init(op_code, rc, ra, rb) } func (this *Stmt) InitRrrcStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { this.stmt_type = RRRC this.rrrc_stmt = new(instruction.RrrcStmt) this.rrrc_stmt.Init(op_code, rc, ra, rb, condition) } func (this *Stmt) InitRrrciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRRCI this.rrrci_stmt = new(instruction.RrrciStmt) this.rrrci_stmt.Init(op_code, rc, ra, rb, condition, pc) } func (this *Stmt) InitRrriStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { this.stmt_type = RRRI this.rrri_stmt = new(instruction.RrriStmt) this.rrri_stmt.Init(op_code, rc, ra, rb, imm) } func (this *Stmt) InitRrriciStmt( op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = RRRICI this.rrrici_stmt = new(instruction.RrriciStmt) this.rrrici_stmt.Init(op_code, rc, ra, rb, imm, condition, pc) } func (this *Stmt) InitSErriStmt( op_code *expr.Expr, suffix *expr.Expr, endian *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = S_ERRI this.s_erri_stmt = new(instruction.SErriStmt) this.s_erri_stmt.Init(op_code, suffix, endian, dc, ra, off) } func (this *Stmt) InitSRStmt(op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token) { this.stmt_type = S_R this.s_r_stmt = new(instruction.SRStmt) this.s_r_stmt.Init(op_code, suffix, dc) } func (this *Stmt) InitSRciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RCI this.s_rci_stmt = new(instruction.SRciStmt) this.s_rci_stmt.Init(op_code, suffix, dc, condition, pc) } func (this *Stmt) InitSRircStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RIRC this.s_rirc_stmt = new(instruction.SRircStmt) this.s_rirc_stmt.Init(op_code, suffix, dc, imm, ra, condition) } func (this *Stmt) InitSRirciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RIRCI this.s_rirci_stmt = new(instruction.SRirciStmt) this.s_rirci_stmt.Init(op_code, suffix, dc, imm, ra, condition, pc) } func (this *Stmt) InitSRrStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, ) { this.stmt_type = S_RR this.s_rr_stmt = new(instruction.SRrStmt) this.s_rr_stmt.Init(op_code, suffix, dc, ra) } func (this *Stmt) InitSRrcStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRC this.s_rrc_stmt = new(instruction.SRrcStmt) this.s_rrc_stmt.Init(op_code, suffix, dc, ra, condition) } func (this *Stmt) InitSRrciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRCI this.s_rrci_stmt = new(instruction.SRrciStmt) this.s_rrci_stmt.Init(op_code, suffix, dc, ra, condition, pc) } func (this *Stmt) InitSRriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, ) { this.stmt_type = S_RRI this.s_rri_stmt = new(instruction.SRriStmt) this.s_rri_stmt.Init(op_code, suffix, dc, ra, imm) } func (this *Stmt) InitSRricStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRIC this.s_rric_stmt = new(instruction.SRricStmt) this.s_rric_stmt.Init(op_code, suffix, dc, ra, imm, condition) } func (this *Stmt) InitSRriciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRICI this.s_rrici_stmt = new(instruction.SRriciStmt) this.s_rrici_stmt.Init(op_code, suffix, dc, ra, imm, condition, pc) } func (this *Stmt) InitSRrrStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, ) { this.stmt_type = S_RRR this.s_rrr_stmt = new(instruction.SRrrStmt) this.s_rrr_stmt.Init(op_code, suffix, dc, ra, rb) } func (this *Stmt) InitSRrrcStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, ) { this.stmt_type = S_RRRC this.s_rrrc_stmt = new(instruction.SRrrcStmt) this.s_rrrc_stmt.Init(op_code, suffix, dc, ra, rb, condition) } func (this *Stmt) InitSRrrciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRRCI this.s_rrrci_stmt = new(instruction.SRrrciStmt) this.s_rrrci_stmt.Init(op_code, suffix, dc, ra, rb, condition, pc) } func (this *Stmt) InitSRrriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, ) { this.stmt_type = S_RRRI this.s_rrri_stmt = new(instruction.SRrriStmt) this.s_rrri_stmt.Init(op_code, suffix, dc, ra, rb, imm) } func (this *Stmt) InitSRrriciStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, rb *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = S_RRRICI this.s_rrrici_stmt = new(instruction.SRrriciStmt) this.s_rrrici_stmt.Init(op_code, suffix, dc, ra, rb, imm, condition, pc) } func (this *Stmt) InitBkpStmt() { this.stmt_type = BKP this.bkp_stmt = new(sugar.BkpStmt) this.bkp_stmt.Init() } func (this *Stmt) InitBootRiStmt(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr) { this.stmt_type = BOOT_RI this.boot_ri_stmt = new(sugar.BootRiStmt) this.boot_ri_stmt.Init(op_code, ra, imm) } func (this *Stmt) InitCallRiStmt(rc *expr.Expr, imm *expr.Expr) { this.stmt_type = CALL_RI this.call_ri_stmt = new(sugar.CallRiStmt) this.call_ri_stmt.Init(rc, imm) } func (this *Stmt) InitCallRrStmt(rc *expr.Expr, ra *expr.Expr) { this.stmt_type = CALL_RR this.call_rr_stmt = new(sugar.CallRrStmt) this.call_rr_stmt.Init(rc, ra) } func (this *Stmt) InitDivStepDrdiStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, ) { this.stmt_type = DIV_STEP_DRDI this.div_step_drdi_stmt = new(sugar.DivStepDrdiStmt) this.div_step_drdi_stmt.Init(op_code, dc, ra, db, imm) } func (this *Stmt) InitJeqRiiStmt(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, pc *expr.Expr) { this.stmt_type = JEQ_RII this.jeq_rii_stmt = new(sugar.JeqRiiStmt) this.jeq_rii_stmt.Init(op_code, ra, imm, pc) } func (this *Stmt) InitJeqRriStmt(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, pc *expr.Expr) { this.stmt_type = JEQ_RRI this.jeq_rri_stmt = new(sugar.JeqRriStmt) this.jeq_rri_stmt.Init(op_code, ra, rb, pc) } func (this *Stmt) InitJnzRiStmt(op_code *expr.Expr, ra *expr.Expr, pc *expr.Expr) { this.stmt_type = JNZ_RI this.jnz_ri_stmt = new(sugar.JnzRiStmt) this.jnz_ri_stmt.Init(op_code, ra, pc) } func (this *Stmt) InitJumpIStmt(pc *expr.Expr) { this.stmt_type = JUMP_I this.jump_i_stmt = new(sugar.JumpIStmt) this.jump_i_stmt.Init(pc) } func (this *Stmt) InitJumpRStmt(ra *expr.Expr) { this.stmt_type = JUMP_R this.jump_r_stmt = new(sugar.JumpRStmt) this.jump_r_stmt.Init(ra) } func (this *Stmt) InitLbsRriStmt(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr) { this.stmt_type = LBS_RRI this.lbs_rri_stmt = new(sugar.LbsRriStmt) this.lbs_rri_stmt.Init(op_code, rc, ra, off) } func (this *Stmt) InitLbsSRriStmt( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = LBS_S_RRI this.lbs_s_rri_stmt = new(sugar.LbsSRriStmt) this.lbs_s_rri_stmt.Init(op_code, suffix, dc, ra, off) } func (this *Stmt) InitLdDriStmt( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { this.stmt_type = LD_DRI this.ld_dri_stmt = new(sugar.LdDriStmt) this.ld_dri_stmt.Init(op_code, dc, ra, off) } func (this *Stmt) InitMovdDdStmt(op_code *expr.Expr, dc *lexer.Token, db *lexer.Token) { this.stmt_type = MOVD_DD this.movd_dd_stmt = new(sugar.MovdDdStmt) this.movd_dd_stmt.Init(op_code, dc, db) } func (this *Stmt) InitMoveRiStmt(rc *expr.Expr, imm *expr.Expr) { this.stmt_type = MOVE_RI this.move_ri_stmt = new(sugar.MoveRiStmt) this.move_ri_stmt.Init(rc, imm) } func (this *Stmt) InitMoveRiciStmt( rc *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = MOVE_RICI this.move_rici_stmt = new(sugar.MoveRiciStmt) this.move_rici_stmt.Init(rc, imm, condition, pc) } func (this *Stmt) InitMoveSRiStmt(suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr) { this.stmt_type = MOVE_S_RI this.move_s_ri_stmt = new(sugar.MoveSRiStmt) this.move_s_ri_stmt.Init(suffix, dc, imm) } func (this *Stmt) InitMoveSRiciStmt( suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { this.stmt_type = MOVE_S_RICI this.move_s_rici_stmt = new(sugar.MoveSRiciStmt) this.move_s_rici_stmt.Init(suffix, dc, imm, condition, pc) } func (this *Stmt) InitSbIdRiStmt(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr) { this.stmt_type = SB_ID_RI this.sb_id_ri_stmt = new(sugar.SbIdRiStmt) this.sb_id_ri_stmt.Init(op_code, ra, off) } func (this *Stmt) InitSbIdRiiStmt( op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr, ) { this.stmt_type = SB_ID_RII this.sb_id_rii_stmt = new(sugar.SbIdRiiStmt) this.sb_id_rii_stmt.Init(op_code, ra, off, imm) } func (this *Stmt) InitSbRirStmt(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr) { this.stmt_type = SB_RIR this.sb_rir_stmt = new(sugar.SbRirStmt) this.sb_rir_stmt.Init(op_code, ra, off, rb) } func (this *Stmt) InitSdRidStmt( op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token, ) { this.stmt_type = SD_RID this.sd_rid_stmt = new(sugar.SdRidStmt) this.sd_rid_stmt.Init(op_code, ra, off, db) } func (this *Stmt) InitStopStmt() { this.stmt_type = STOP this.stop_stmt = new(sugar.StopStmt) this.stop_stmt.Init() } func (this *Stmt) InitTimeCfgRStmt(ra *expr.Expr) { this.stmt_type = TIME_CFG_R this.time_cfg_r_stmt = new(sugar.TimeCfgRStmt) this.time_cfg_r_stmt.Init(ra) } func (this *Stmt) InitLabelStmt(expr_ *expr.Expr) { this.stmt_type = LABEL this.label_stmt = new(LabelStmt) this.label_stmt.Init(expr_) } func (this *Stmt) StmtType() StmtType { return this.stmt_type } func (this *Stmt) AddrsigStmt() *directive.AddrsigStmt { return this.addrsig_stmt } func (this *Stmt) AddrsigSymStmt() *directive.AddrsigSymStmt { return this.addrsig_sym_stmt } func (this *Stmt) AsciiStmt() *directive.AsciiStmt { return this.ascii_stmt } func (this *Stmt) AscizStmt() *directive.AscizStmt { return this.asciz_stmt } func (this *Stmt) ByteStmt() *directive.ByteStmt { return this.byte_stmt } func (this *Stmt) CfiDefCfaOffsetStmt() *directive.CfiDefCfaOffsetStmt { return this.cfi_def_cfa_offset_stmt } func (this *Stmt) CfiEndprocStmt() *directive.CfiEndprocStmt { return this.cfi_endproc_stmt } func (this *Stmt) CfiOffsetStmt() *directive.CfiOffsetStmt { return this.cfi_offset_stmt } func (this *Stmt) CfiSectionsStmt() *directive.CfiSectionsStmt { return this.cfi_sections_stmt } func (this *Stmt) CfiStartprocStmt() *directive.CfiStartprocStmt { return this.cfi_startproc_stmt } func (this *Stmt) FileNumberStmt() *directive.FileNumberStmt { return this.file_number_stmt } func (this *Stmt) FileStringStmt() *directive.FileStringStmt { return this.file_string_stmt } func (this *Stmt) GlobalStmt() *directive.GlobalStmt { return this.global_stmt } func (this *Stmt) LocIsStmtStmt() *directive.LocIsStmtStmt { return this.loc_is_stmt_stmt } func (this *Stmt) LocNumberStmt() *directive.LocNumberStmt { return this.loc_number_stmt } func (this *Stmt) LocPrologueEndStmt() *directive.LocPrologueEndStmt { return this.loc_prologue_end_stmt } func (this *Stmt) LongProgramCounterStmt() *directive.LongProgramCounterStmt { return this.long_program_counter_stmt } func (this *Stmt) LongSectionNameStmt() *directive.LongSectionNameStmt { return this.long_section_name_stmt } func (this *Stmt) P2AlignStmt() *directive.P2AlignStmt { return this.p2_align_stmt } func (this *Stmt) QuadStmt() *directive.QuadStmt { return this.quad_stmt } func (this *Stmt) SectionIdentifierNumberStmt() *directive.SectionIdentifierNumberStmt { return this.section_identifier_number_stmt } func (this *Stmt) SectionIdentifierStmt() *directive.SectionIdentifierStmt { return this.section_identifier_stmt } func (this *Stmt) SectionStackSizesStmt() *directive.SectionStackSizesStmt { return this.section_stack_sizes_stmt } func (this *Stmt) SectionStringNumberStmt() *directive.SectionStringNumberStmt { return this.section_string_number_stmt } func (this *Stmt) SectionStringStmt() *directive.SectionStringStmt { return this.section_string_stmt } func (this *Stmt) SetStmt() *directive.SetStmt { return this.set_stmt } func (this *Stmt) ShortStmt() *directive.ShortStmt { return this.short_stmt } func (this *Stmt) SizeStmt() *directive.SizeStmt { return this.size_stmt } func (this *Stmt) TextStmt() *directive.TextStmt { return this.text_stmt } func (this *Stmt) TypeStmt() *directive.TypeStmt { return this.type_stmt } func (this *Stmt) WeakStmt() *directive.WeakStmt { return this.weak_stmt } func (this *Stmt) ZeroSingleNumberStmt() *directive.ZeroSingleNumberStmt { return this.zero_single_number_stmt } func (this *Stmt) ZeroDoubleNumberStmt() *directive.ZeroDoubleNumberStmt { return this.zero_double_number_stmt } func (this *Stmt) CiStmt() *instruction.CiStmt { return this.ci_stmt } func (this *Stmt) DdciStmt() *instruction.DdciStmt { return this.ddci_stmt } func (this *Stmt) DmaRriStmt() *instruction.DmaRriStmt { return this.dma_rri_stmt } func (this *Stmt) DrdiciStmt() *instruction.DrdiciStmt { return this.drdici_stmt } func (this *Stmt) EdriStmt() *instruction.EdriStmt { return this.edri_stmt } func (this *Stmt) EridStmt() *instruction.EridStmt { return this.erid_stmt } func (this *Stmt) EriiStmt() *instruction.EriiStmt { return this.erii_stmt } func (this *Stmt) ErirStmt() *instruction.ErirStmt { return this.erir_stmt } func (this *Stmt) ErriStmt() *instruction.ErriStmt { return this.erri_stmt } func (this *Stmt) IStmt() *instruction.IStmt { return this.i_stmt } func (this *Stmt) NopStmt() *instruction.NopStmt { return this.nop_stmt } func (this *Stmt) RStmt() *instruction.RStmt { return this.r_stmt } func (this *Stmt) RciStmt() *instruction.RciStmt { return this.rci_stmt } func (this *Stmt) RiciStmt() *instruction.RiciStmt { return this.rici_stmt } func (this *Stmt) RirStmt() *instruction.RirStmt { return this.rir_stmt } func (this *Stmt) RircStmt() *instruction.RircStmt { return this.rirc_stmt } func (this *Stmt) RirciStmt() *instruction.RirciStmt { return this.rirci_stmt } func (this *Stmt) RrStmt() *instruction.RrStmt { return this.rr_stmt } func (this *Stmt) RrcStmt() *instruction.RrcStmt { return this.rrc_stmt } func (this *Stmt) RrciStmt() *instruction.RrciStmt { return this.rrci_stmt } func (this *Stmt) RriStmt() *instruction.RriStmt { return this.rri_stmt } func (this *Stmt) RricStmt() *instruction.RricStmt { return this.rric_stmt } func (this *Stmt) RriciStmt() *instruction.RriciStmt { return this.rrici_stmt } func (this *Stmt) RrrStmt() *instruction.RrrStmt { return this.rrr_stmt } func (this *Stmt) RrrcStmt() *instruction.RrrcStmt { return this.rrrc_stmt } func (this *Stmt) RrrciStmt() *instruction.RrrciStmt { return this.rrrci_stmt } func (this *Stmt) RrriStmt() *instruction.RrriStmt { return this.rrri_stmt } func (this *Stmt) RrriciStmt() *instruction.RrriciStmt { return this.rrrici_stmt } func (this *Stmt) SErriStmt() *instruction.SErriStmt { return this.s_erri_stmt } func (this *Stmt) SRStmt() *instruction.SRStmt { return this.s_r_stmt } func (this *Stmt) SRciStmt() *instruction.SRciStmt { return this.s_rci_stmt } func (this *Stmt) SRircStmt() *instruction.SRircStmt { return this.s_rirc_stmt } func (this *Stmt) SRirciStmt() *instruction.SRirciStmt { return this.s_rirci_stmt } func (this *Stmt) SRrStmt() *instruction.SRrStmt { return this.s_rr_stmt } func (this *Stmt) SRrcStmt() *instruction.SRrcStmt { return this.s_rrc_stmt } func (this *Stmt) SRrciStmt() *instruction.SRrciStmt { return this.s_rrci_stmt } func (this *Stmt) SRriStmt() *instruction.SRriStmt { return this.s_rri_stmt } func (this *Stmt) SRricStmt() *instruction.SRricStmt { return this.s_rric_stmt } func (this *Stmt) SRriciStmt() *instruction.SRriciStmt { return this.s_rrici_stmt } func (this *Stmt) SRrrStmt() *instruction.SRrrStmt { return this.s_rrr_stmt } func (this *Stmt) SRrrcStmt() *instruction.SRrrcStmt { return this.s_rrrc_stmt } func (this *Stmt) SRrrciStmt() *instruction.SRrrciStmt { return this.s_rrrci_stmt } func (this *Stmt) SRrriStmt() *instruction.SRrriStmt { return this.s_rrri_stmt } func (this *Stmt) SRrriciStmt() *instruction.SRrriciStmt { return this.s_rrrici_stmt } func (this *Stmt) BkpStmt() *sugar.BkpStmt { return this.bkp_stmt } func (this *Stmt) BootRiStmt() *sugar.BootRiStmt { return this.boot_ri_stmt } func (this *Stmt) CallRiStmt() *sugar.CallRiStmt { return this.call_ri_stmt } func (this *Stmt) CallRrStmt() *sugar.CallRrStmt { return this.call_rr_stmt } func (this *Stmt) DivStepDrdiStmt() *sugar.DivStepDrdiStmt { return this.div_step_drdi_stmt } func (this *Stmt) JeqRiiStmt() *sugar.JeqRiiStmt { return this.jeq_rii_stmt } func (this *Stmt) JeqRriStmt() *sugar.JeqRriStmt { return this.jeq_rri_stmt } func (this *Stmt) JnzRiStmt() *sugar.JnzRiStmt { return this.jnz_ri_stmt } func (this *Stmt) JumpIStmt() *sugar.JumpIStmt { return this.jump_i_stmt } func (this *Stmt) JumpRStmt() *sugar.JumpRStmt { return this.jump_r_stmt } func (this *Stmt) LbsRriStmt() *sugar.LbsRriStmt { return this.lbs_rri_stmt } func (this *Stmt) LbsSRriStmt() *sugar.LbsSRriStmt { return this.lbs_s_rri_stmt } func (this *Stmt) LdDriStmt() *sugar.LdDriStmt { return this.ld_dri_stmt } func (this *Stmt) MovdDdStmt() *sugar.MovdDdStmt { return this.movd_dd_stmt } func (this *Stmt) MoveRiStmt() *sugar.MoveRiStmt { return this.move_ri_stmt } func (this *Stmt) MoveRiciStmt() *sugar.MoveRiciStmt { return this.move_rici_stmt } func (this *Stmt) MoveSRiStmt() *sugar.MoveSRiStmt { return this.move_s_ri_stmt } func (this *Stmt) MoveSRiciStmt() *sugar.MoveSRiciStmt { return this.move_s_rici_stmt } func (this *Stmt) SbIdRiStmt() *sugar.SbIdRiStmt { return this.sb_id_ri_stmt } func (this *Stmt) SbIdRiiStmt() *sugar.SbIdRiiStmt { return this.sb_id_rii_stmt } func (this *Stmt) SbRirStmt() *sugar.SbRirStmt { return this.sb_rir_stmt } func (this *Stmt) SdRidStmt() *sugar.SdRidStmt { return this.sd_rid_stmt } func (this *Stmt) StopStmt() *sugar.StopStmt { return this.stop_stmt } func (this *Stmt) TimeCfgRStmt() *sugar.TimeCfgRStmt { return this.time_cfg_r_stmt } func (this *Stmt) LabelStmt() *LabelStmt { return this.label_stmt } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/bkp_stmt.go ================================================ package sugar type BkpStmt struct { } func (this *BkpStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/boot_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type BootRiStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr } func (this *BootRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.RICI_OP_CODE { err := errors.New("op code is not an RICI op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm } func (this *BootRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *BootRiStmt) Ra() *expr.Expr { return this.ra } func (this *BootRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/call_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CallRiStmt struct { rc *expr.Expr imm *expr.Expr } func (this *CallRiStmt) Init(rc *expr.Expr, imm *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.rc = rc this.imm = imm } func (this *CallRiStmt) Rc() *expr.Expr { return this.rc } func (this *CallRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/call_rr_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type CallRrStmt struct { rc *expr.Expr ra *expr.Expr } func (this *CallRrStmt) Init(rc *expr.Expr, ra *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.rc = rc this.ra = ra } func (this *CallRrStmt) Rc() *expr.Expr { return this.rc } func (this *CallRrStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/div_step_drdi_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type DivStepDrdiStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr db *lexer.Token imm *expr.Expr } func (this *DivStepDrdiStmt) Init( op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, db *lexer.Token, imm *expr.Expr, ) { if op_code.ExprType() != expr.DRDICI_OP_CODE { err := errors.New("op code is not a DRDICI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.db = db this.imm = imm } func (this *DivStepDrdiStmt) OpCode() *expr.Expr { return this.op_code } func (this *DivStepDrdiStmt) Dc() *lexer.Token { return this.dc } func (this *DivStepDrdiStmt) Ra() *expr.Expr { return this.ra } func (this *DivStepDrdiStmt) Db() *lexer.Token { return this.db } func (this *DivStepDrdiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/jeq_rii_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type JeqRiiStmt struct { op_code *expr.Expr ra *expr.Expr imm *expr.Expr pc *expr.Expr } func (this *JeqRiiStmt) Init(op_code *expr.Expr, ra *expr.Expr, imm *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.imm = imm this.pc = pc } func (this *JeqRiiStmt) OpCode() *expr.Expr { return this.op_code } func (this *JeqRiiStmt) Ra() *expr.Expr { return this.ra } func (this *JeqRiiStmt) Imm() *expr.Expr { return this.imm } func (this *JeqRiiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/jeq_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type JeqRriStmt struct { op_code *expr.Expr ra *expr.Expr rb *expr.Expr pc *expr.Expr } func (this *JeqRriStmt) Init(op_code *expr.Expr, ra *expr.Expr, rb *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.rb = rb this.pc = pc } func (this *JeqRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *JeqRriStmt) Ra() *expr.Expr { return this.ra } func (this *JeqRriStmt) Rb() *expr.Expr { return this.rb } func (this *JeqRriStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/jnz_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type JnzRiStmt struct { op_code *expr.Expr ra *expr.Expr pc *expr.Expr } func (this *JnzRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, pc *expr.Expr) { if op_code.ExprType() != expr.JUMP_OP_CODE { err := errors.New("op code is not a jump op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.pc = pc } func (this *JnzRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *JnzRiStmt) Ra() *expr.Expr { return this.ra } func (this *JnzRiStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/jump_i_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type JumpIStmt struct { pc *expr.Expr } func (this *JumpIStmt) Init(pc *expr.Expr) { if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.pc = pc } func (this *JumpIStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/jump_r_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type JumpRStmt struct { ra *expr.Expr } func (this *JumpRStmt) Init(ra *expr.Expr) { if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.ra = ra } func (this *JumpRStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/lbs_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type LbsRriStmt struct { op_code *expr.Expr rc *expr.Expr ra *expr.Expr off *expr.Expr } func (this *LbsRriStmt) Init(op_code *expr.Expr, rc *expr.Expr, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.rc = rc this.ra = ra this.off = off } func (this *LbsRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LbsRriStmt) Rc() *expr.Expr { return this.rc } func (this *LbsRriStmt) Ra() *expr.Expr { return this.ra } func (this *LbsRriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/lbs_s_rri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type LbsSRriStmt struct { op_code *expr.Expr suffix *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *LbsSRriStmt) Init( op_code *expr.Expr, suffix *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr, ) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.suffix = suffix this.dc = dc this.ra = ra this.off = off } func (this *LbsSRriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LbsSRriStmt) Suffix() *expr.Expr { return this.suffix } func (this *LbsSRriStmt) Dc() *lexer.Token { return this.dc } func (this *LbsSRriStmt) Ra() *expr.Expr { return this.ra } func (this *LbsSRriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/ld_dri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type LdDriStmt struct { op_code *expr.Expr dc *lexer.Token ra *expr.Expr off *expr.Expr } func (this *LdDriStmt) Init(op_code *expr.Expr, dc *lexer.Token, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.LOAD_OP_CODE { err := errors.New("op code is not a load op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.dc = dc this.ra = ra this.off = off } func (this *LdDriStmt) OpCode() *expr.Expr { return this.op_code } func (this *LdDriStmt) Dc() *lexer.Token { return this.dc } func (this *LdDriStmt) Ra() *expr.Expr { return this.ra } func (this *LdDriStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/movd_dd_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type MovdDdStmt struct { op_code *expr.Expr dc *lexer.Token db *lexer.Token } func (this *MovdDdStmt) Init(op_code *expr.Expr, dc *lexer.Token, db *lexer.Token) { if op_code.ExprType() != expr.DDCI_OP_CODE { err := errors.New("op code is not a DDCI op code") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("db is not a pair reg") panic(err) } this.op_code = op_code this.dc = dc this.db = db } func (this *MovdDdStmt) OpCode() *expr.Expr { return this.op_code } func (this *MovdDdStmt) Dc() *lexer.Token { return this.dc } func (this *MovdDdStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/move_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type MoveRiStmt struct { rc *expr.Expr imm *expr.Expr } func (this *MoveRiStmt) Init(rc *expr.Expr, imm *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.rc = rc this.imm = imm } func (this *MoveRiStmt) Rc() *expr.Expr { return this.rc } func (this *MoveRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/move_rici_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type MoveRiciStmt struct { rc *expr.Expr imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *MoveRiciStmt) Init(rc *expr.Expr, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr) { if rc.ExprType() != expr.SRC_REG { err := errors.New("rc is not a src reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.rc = rc this.imm = imm this.condition = condition this.pc = pc } func (this *MoveRiciStmt) Rc() *expr.Expr { return this.rc } func (this *MoveRiciStmt) Imm() *expr.Expr { return this.imm } func (this *MoveRiciStmt) Condition() *expr.Expr { return this.condition } func (this *MoveRiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/move_s_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type MoveSRiStmt struct { suffix *expr.Expr dc *lexer.Token imm *expr.Expr } func (this *MoveSRiStmt) Init(suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr) { if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.suffix = suffix this.dc = dc this.imm = imm } func (this *MoveSRiStmt) Suffix() *expr.Expr { return this.suffix } func (this *MoveSRiStmt) Dc() *lexer.Token { return this.dc } func (this *MoveSRiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/move_s_rici_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type MoveSRiciStmt struct { suffix *expr.Expr dc *lexer.Token imm *expr.Expr condition *expr.Expr pc *expr.Expr } func (this *MoveSRiciStmt) Init( suffix *expr.Expr, dc *lexer.Token, imm *expr.Expr, condition *expr.Expr, pc *expr.Expr, ) { if suffix.ExprType() != expr.SUFFIX { err := errors.New("suffix is not a suffix") panic(err) } if dc.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } if condition.ExprType() != expr.CONDITION { err := errors.New("condition is not a condition") panic(err) } if pc.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("pc is not a program counter") panic(err) } this.suffix = suffix this.dc = dc this.imm = imm this.condition = condition this.pc = pc } func (this *MoveSRiciStmt) Suffix() *expr.Expr { return this.suffix } func (this *MoveSRiciStmt) Dc() *lexer.Token { return this.dc } func (this *MoveSRiciStmt) Imm() *expr.Expr { return this.imm } func (this *MoveSRiciStmt) Condition() *expr.Expr { return this.condition } func (this *MoveSRiciStmt) Pc() *expr.Expr { return this.pc } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/sb_id_ri_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type SbIdRiStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr } func (this *SbIdRiStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.off = off } func (this *SbIdRiStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbIdRiStmt) Ra() *expr.Expr { return this.ra } func (this *SbIdRiStmt) Off() *expr.Expr { return this.off } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/sb_id_rii_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type SbIdRiiStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr imm *expr.Expr } func (this *SbIdRiiStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, imm *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if imm.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("imm is not a program counter") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.imm = imm } func (this *SbIdRiiStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbIdRiiStmt) Ra() *expr.Expr { return this.ra } func (this *SbIdRiiStmt) Off() *expr.Expr { return this.off } func (this *SbIdRiiStmt) Imm() *expr.Expr { return this.imm } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/sb_rir_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type SbRirStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr rb *expr.Expr } func (this *SbRirStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, rb *expr.Expr) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if rb.ExprType() != expr.SRC_REG { err := errors.New("rb is not a src reg") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.rb = rb } func (this *SbRirStmt) OpCode() *expr.Expr { return this.op_code } func (this *SbRirStmt) Ra() *expr.Expr { return this.ra } func (this *SbRirStmt) Off() *expr.Expr { return this.off } func (this *SbRirStmt) Rb() *expr.Expr { return this.rb } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/sd_rid_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/lexer" "uPIMulator/src/device/linker/parser/expr" ) type SdRidStmt struct { op_code *expr.Expr ra *expr.Expr off *expr.Expr db *lexer.Token } func (this *SdRidStmt) Init(op_code *expr.Expr, ra *expr.Expr, off *expr.Expr, db *lexer.Token) { if op_code.ExprType() != expr.STORE_OP_CODE { err := errors.New("op code is not a store op code") panic(err) } if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } if off.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("off is not a program counter") panic(err) } if db.TokenType() != lexer.PAIR_REG { err := errors.New("dc is not a pair reg") panic(err) } this.op_code = op_code this.ra = ra this.off = off this.db = db } func (this *SdRidStmt) OpCode() *expr.Expr { return this.op_code } func (this *SdRidStmt) Ra() *expr.Expr { return this.ra } func (this *SdRidStmt) Off() *expr.Expr { return this.off } func (this *SdRidStmt) Db() *lexer.Token { return this.db } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/stop_stmt.go ================================================ package sugar type StopStmt struct { } func (this *StopStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/stmt/sugar/time_cfg_r_stmt.go ================================================ package sugar import ( "errors" "uPIMulator/src/device/linker/parser/expr" ) type TimeCfgRStmt struct { ra *expr.Expr } func (this *TimeCfgRStmt) Init(ra *expr.Expr) { if ra.ExprType() != expr.SRC_REG { err := errors.New("ra is not a src reg") panic(err) } this.ra = ra } func (this *TimeCfgRStmt) Ra() *expr.Expr { return this.ra } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/table.go ================================================ package parser import ( "errors" "uPIMulator/src/device/linker/lexer" ) type Table struct { expr_rules []*Rule stmt_rules []*Rule stack *Stack } func (this *Table) Init(stack *Stack) { this.expr_rules = make([]*Rule, 0) this.stmt_rules = make([]*Rule, 0) this.stack = stack } func (this *Table) AddExprRule(rule *Rule) { this.expr_rules = append(this.expr_rules, rule) } func (this *Table) AddStmtRule(rule *Rule) { this.stmt_rules = append(this.stmt_rules, rule) } func (this *Table) FindReducibleExprRule(token *lexer.Token) (*Rule, []*StackItem) { for num := this.stack.NonStmtLength(); num > 0; num-- { stack_items := this.stack.Front(num) for _, expr_rule := range this.expr_rules { if expr_rule.IsReducible(stack_items, token) { return expr_rule, stack_items } } } return nil, []*StackItem{} } func (this *Table) FindReducibleStmtRule(token *lexer.Token) (*Rule, []*StackItem) { if token.TokenType() != lexer.NEW_LINE { err := errors.New("token is not a new line") panic(err) } num := this.stack.NonStmtLength() stack_items := this.stack.Front(num) for _, stmt_rule := range this.stmt_rules { if stmt_rule.IsReducible(stack_items, token) { return stmt_rule, stack_items } } return nil, []*StackItem{} } ================================================ FILE: golang_vm/uPIMulator/src/device/linker/parser/walker.go ================================================ package parser import ( "errors" "uPIMulator/src/device/linker/parser/expr" "uPIMulator/src/device/linker/parser/stmt" ) type ExprCallback func(*expr.Expr) type StmtCallback func(*stmt.Stmt) type Walker struct { expr_callbacks map[expr.ExprType]ExprCallback stmt_callbacks map[stmt.StmtType]StmtCallback } func (this *Walker) Init() { this.expr_callbacks = make(map[expr.ExprType]ExprCallback) this.stmt_callbacks = make(map[stmt.StmtType]StmtCallback) } func (this *Walker) RegisterExprCallback(expr_type expr.ExprType, expr_callback ExprCallback) { if _, found := this.expr_callbacks[expr_type]; found { err := errors.New("expr callbak is already registered") panic(err) } this.expr_callbacks[expr_type] = expr_callback } func (this *Walker) RegisterStmtCallback(stmt_type stmt.StmtType, stmt_callback StmtCallback) { if _, found := this.stmt_callbacks[stmt_type]; found { err := errors.New("stmt callbak is already registered") panic(err) } this.stmt_callbacks[stmt_type] = stmt_callback } func (this *Walker) Walk(ast *Ast) { for i := 0; i < ast.Length(); i++ { stmt_ := ast.Get(i) stmt_type := stmt_.StmtType() if stmt_type == stmt.ASCII { this.WalkAsciiStmt(stmt_) } else if stmt_type == stmt.ASCIZ { this.WalkAscizStmt(stmt_) } else if stmt_type == stmt.BYTE { this.WalkByteStmt(stmt_) } else if stmt_type == stmt.GLOBAL { this.WalkGlobalStmt(stmt_) } else if stmt_type == stmt.LONG_PROGRAM_COUNTER { this.WalkLongProgramCounterStmt(stmt_) } else if stmt_type == stmt.LONG_SECTION_NAME { this.WalkLongSectionNameStmt(stmt_) } else if stmt_type == stmt.P2_ALIGN { this.WalkP2AlignStmt(stmt_) } else if stmt_type == stmt.QUAD { this.WalkQuadStmt(stmt_) } else if stmt_type == stmt.SECTION_IDENTIFIER_NUMBER { this.WalkSectionIdentifierNumberStmt(stmt_) } else if stmt_type == stmt.SECTION_IDENTIFIER { this.WalkSectionIdentifierStmt(stmt_) } else if stmt_type == stmt.SECTION_STACK_SIZES { this.WalkSectionStackSizesStmt(stmt_) } else if stmt_type == stmt.SECTION_STRING_NUMBER { this.WalkSectionStringNumberStmt(stmt_) } else if stmt_type == stmt.SECTION_STRING { this.WalkSectionStringStmt(stmt_) } else if stmt_type == stmt.SET { this.WalkSetStmt(stmt_) } else if stmt_type == stmt.SHORT { this.WalkShortStmt(stmt_) } else if stmt_type == stmt.SIZE { this.WalkSizeStmt(stmt_) } else if stmt_type == stmt.TEXT { this.WalkTextStmt(stmt_) } else if stmt_type == stmt.ZERO_DOUBLE_NUMBER { this.WalkZeroDoubleNumberStmt(stmt_) } else if stmt_type == stmt.ZERO_SINGLE_NUMBER { this.WalkZeroSingleNumberStmt(stmt_) } else if stmt_type == stmt.CI { this.WalkCiStmt(stmt_) } else if stmt_type == stmt.DDCI { this.WalkDdciStmt(stmt_) } else if stmt_type == stmt.DMA_RRI { this.WalkDmaRriStmt(stmt_) } else if stmt_type == stmt.DRDICI { this.WalkDrdiciStmt(stmt_) } else if stmt_type == stmt.EDRI { this.WalkEdriStmt(stmt_) } else if stmt_type == stmt.ERID { this.WalkEridStmt(stmt_) } else if stmt_type == stmt.ERII { this.WalkEriiStmt(stmt_) } else if stmt_type == stmt.ERIR { this.WalkErirStmt(stmt_) } else if stmt_type == stmt.ERRI { this.WalkErriStmt(stmt_) } else if stmt_type == stmt.I { this.WalkIStmt(stmt_) } else if stmt_type == stmt.NOP { this.WalkNopStmt(stmt_) } else if stmt_type == stmt.RCI { this.WalkRciStmt(stmt_) } else if stmt_type == stmt.RICI { this.WalkRiciStmt(stmt_) } else if stmt_type == stmt.RIRCI { this.WalkRirciStmt(stmt_) } else if stmt_type == stmt.RIRC { this.WalkRircStmt(stmt_) } else if stmt_type == stmt.RIR { this.WalkRirStmt(stmt_) } else if stmt_type == stmt.RRCI { this.WalkRrciStmt(stmt_) } else if stmt_type == stmt.RRC { this.WalkRrcStmt(stmt_) } else if stmt_type == stmt.RRICI { this.WalkRriciStmt(stmt_) } else if stmt_type == stmt.RRIC { this.WalkRricStmt(stmt_) } else if stmt_type == stmt.RRI { this.WalkRriStmt(stmt_) } else if stmt_type == stmt.RRRCI { this.WalkRrrciStmt(stmt_) } else if stmt_type == stmt.RRRC { this.WalkRrrcStmt(stmt_) } else if stmt_type == stmt.RRRICI { this.WalkRrriciStmt(stmt_) } else if stmt_type == stmt.RRRI { this.WalkRrriStmt(stmt_) } else if stmt_type == stmt.RRR { this.WalkRrrStmt(stmt_) } else if stmt_type == stmt.RR { this.WalkRrStmt(stmt_) } else if stmt_type == stmt.R { this.WalkRStmt(stmt_) } else if stmt_type == stmt.S_ERRI { this.WalkSErriStmt(stmt_) } else if stmt_type == stmt.S_RCI { this.WalkSRciStmt(stmt_) } else if stmt_type == stmt.S_RIRCI { this.WalkSRirciStmt(stmt_) } else if stmt_type == stmt.S_RIRC { this.WalkSRircStmt(stmt_) } else if stmt_type == stmt.S_RRCI { this.WalkSRrciStmt(stmt_) } else if stmt_type == stmt.S_RRC { this.WalkSRrcStmt(stmt_) } else if stmt_type == stmt.S_RRICI { this.WalkSRriciStmt(stmt_) } else if stmt_type == stmt.S_RRIC { this.WalkSRricStmt(stmt_) } else if stmt_type == stmt.S_RRI { this.WalkSRriStmt(stmt_) } else if stmt_type == stmt.S_RRRCI { this.WalkSRrrciStmt(stmt_) } else if stmt_type == stmt.S_RRRC { this.WalkSRrrcStmt(stmt_) } else if stmt_type == stmt.S_RRRICI { this.WalkSRrriciStmt(stmt_) } else if stmt_type == stmt.S_RRRI { this.WalkSRrriStmt(stmt_) } else if stmt_type == stmt.S_RRR { this.WalkSRrrStmt(stmt_) } else if stmt_type == stmt.S_RR { this.WalkSRrStmt(stmt_) } else if stmt_type == stmt.S_R { this.WalkSRStmt(stmt_) } else if stmt_type == stmt.BKP { this.WalkBkpStmt(stmt_) } else if stmt_type == stmt.BOOT_RI { this.WalkBootRiStmt(stmt_) } else if stmt_type == stmt.CALL_RI { this.WalkCallRiStmt(stmt_) } else if stmt_type == stmt.CALL_RR { this.WalkCallRrStmt(stmt_) } else if stmt_type == stmt.DIV_STEP_DRDI { this.WalkDivStepDrdiStmt(stmt_) } else if stmt_type == stmt.JEQ_RII { this.WalkJeqRiiStmt(stmt_) } else if stmt_type == stmt.JEQ_RRI { this.WalkJeqRriStmt(stmt_) } else if stmt_type == stmt.JNZ_RI { this.WalkJnzRiStmt(stmt_) } else if stmt_type == stmt.JUMP_I { this.WalkJumpIStmt(stmt_) } else if stmt_type == stmt.JUMP_R { this.WalkJumpRStmt(stmt_) } else if stmt_type == stmt.LBS_RRI { this.WalkLbsRriStmt(stmt_) } else if stmt_type == stmt.LBS_S_RRI { this.WalkLbsSRriStmt(stmt_) } else if stmt_type == stmt.LD_DRI { this.WalkLdDriStmt(stmt_) } else if stmt_type == stmt.MOVD_DD { this.WalkMovdDdStmt(stmt_) } else if stmt_type == stmt.MOVE_RICI { this.WalkMoveRiciStmt(stmt_) } else if stmt_type == stmt.MOVE_RI { this.WalkMoveRiStmt(stmt_) } else if stmt_type == stmt.MOVE_S_RICI { this.WalkMoveSRiciStmt(stmt_) } else if stmt_type == stmt.MOVE_S_RI { this.WalkMoveSRiStmt(stmt_) } else if stmt_type == stmt.SB_ID_RII { this.WalkSbIdRiiStmt(stmt_) } else if stmt_type == stmt.SB_ID_RI { this.WalkSbIdRiStmt(stmt_) } else if stmt_type == stmt.SB_RIR { this.WalkSbRirStmt(stmt_) } else if stmt_type == stmt.SD_RID { this.WalkSdRidStmt(stmt_) } else if stmt_type == stmt.STOP { this.WalkStopStmt(stmt_) } else if stmt_type == stmt.TIME_CFG_R { this.WalkTimeCfgRStmt(stmt_) } else if stmt_type == stmt.LABEL { this.WalkLabelStmt(stmt_) } else { continue } } } func (this *Walker) WalkBinaryAddExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.BINARY_ADD { err := errors.New("expr type is not binary add expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.BINARY_ADD]; found { expr_callback(expr_) } binary_add_expr := expr_.BinaryAddExpr() operand1 := binary_add_expr.Operand1() operand2 := binary_add_expr.Operand2() this.WalkPrimaryExpr(operand1) this.WalkPrimaryExpr(operand2) } func (this *Walker) WalkBinarySubExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.BINARY_SUB { err := errors.New("expr type is not binary sub expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.BINARY_SUB]; found { expr_callback(expr_) } binary_sub_expr := expr_.BinarySubExpr() operand1 := binary_sub_expr.Operand1() operand2 := binary_sub_expr.Operand2() this.WalkPrimaryExpr(operand1) this.WalkPrimaryExpr(operand2) } func (this *Walker) WalkNegativeNumberExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.NEGATIVE_NUMBER { err := errors.New("expr type is not negative number expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.NEGATIVE_NUMBER]; found { expr_callback(expr_) } } func (this *Walker) WalkPrimaryExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PRIMARY { err := errors.New("expr type is not primary") panic(err) } if expr_callback, found := this.expr_callbacks[expr.PRIMARY]; found { expr_callback(expr_) } } func (this *Walker) WalkProgramCounterExpr(expr_ *expr.Expr) { if expr_.ExprType() != expr.PROGRAM_COUNTER { err := errors.New("expr type is not program counter expr") panic(err) } if expr_callback, found := this.expr_callbacks[expr.PROGRAM_COUNTER]; found { expr_callback(expr_) } program_counter_expr := expr_.ProgramCounterExpr() child_expr := program_counter_expr.Expr() child_expr_type := child_expr.ExprType() if child_expr_type == expr.PRIMARY { this.WalkPrimaryExpr(child_expr) } else if child_expr_type == expr.NEGATIVE_NUMBER { this.WalkNegativeNumberExpr(child_expr) } else if child_expr_type == expr.BINARY_ADD { this.WalkBinaryAddExpr(child_expr) } else if child_expr_type == expr.BINARY_SUB { this.WalkBinarySubExpr(child_expr) } else { err := errors.New("child expr is not valid for a program counter expr") panic(err) } } func (this *Walker) WalkAsciiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ASCII { err := errors.New("stmt type is not an ASCII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ASCII]; found { stmt_callback(stmt_) } } func (this *Walker) WalkAscizStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ASCIZ { err := errors.New("stmt type is not an ASCIZ stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ASCIZ]; found { stmt_callback(stmt_) } } func (this *Walker) WalkByteStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BYTE { err := errors.New("stmt type is not a byte stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BYTE]; found { stmt_callback(stmt_) } byte_stmt := stmt_.ByteStmt() expr_ := byte_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkGlobalStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.GLOBAL { err := errors.New("stmt type is not a global stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.GLOBAL]; found { stmt_callback(stmt_) } global_stmt := stmt_.GlobalStmt() expr_ := global_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkLongProgramCounterStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LONG_PROGRAM_COUNTER { err := errors.New("stmt type is not a long program counter stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LONG_PROGRAM_COUNTER]; found { stmt_callback(stmt_) } long_program_counter_stmt := stmt_.LongProgramCounterStmt() expr_ := long_program_counter_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkLongSectionNameStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LONG_SECTION_NAME { err := errors.New("stmt type is not a long section name stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LONG_SECTION_NAME]; found { stmt_callback(stmt_) } } func (this *Walker) WalkP2AlignStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.P2_ALIGN { err := errors.New("stmt type is not a p2align stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.P2_ALIGN]; found { stmt_callback(stmt_) } } func (this *Walker) WalkQuadStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.QUAD { err := errors.New("stmt type is not a quad stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.QUAD]; found { stmt_callback(stmt_) } quad_stmt := stmt_.QuadStmt() expr_ := quad_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkSectionIdentifierNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_IDENTIFIER_NUMBER { err := errors.New("stmt type is not a section identifier number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_IDENTIFIER_NUMBER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionIdentifierStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_IDENTIFIER { err := errors.New("stmt type is not a section identifier stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_IDENTIFIER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStackSizesStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STACK_SIZES { err := errors.New("stmt type is not a section stack sizes stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STACK_SIZES]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStringNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STRING_NUMBER { err := errors.New("stmt type is not a section string number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STRING_NUMBER]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSectionStringStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SECTION_STRING { err := errors.New("stmt type is not a section string stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SECTION_STRING]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSetStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SET { err := errors.New("stmt type is not a set stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SET]; found { stmt_callback(stmt_) } set_stmt := stmt_.SetStmt() expr1 := set_stmt.Expr1() expr2 := set_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkShortStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SHORT { err := errors.New("stmt type is not a short stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SHORT]; found { stmt_callback(stmt_) } short_stmt := stmt_.ShortStmt() expr_ := short_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkSizeStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SIZE { err := errors.New("stmt type is not a size stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SIZE]; found { stmt_callback(stmt_) } size_stmt := stmt_.SizeStmt() expr1 := size_stmt.Expr1() expr2 := size_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkTextStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.TEXT { err := errors.New("stmt type is not a text stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.TEXT]; found { stmt_callback(stmt_) } } func (this *Walker) WalkZeroDoubleNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ZERO_DOUBLE_NUMBER { err := errors.New("stmt type is not a zero double number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ZERO_DOUBLE_NUMBER]; found { stmt_callback(stmt_) } zero_double_number_stmt := stmt_.ZeroDoubleNumberStmt() expr1 := zero_double_number_stmt.Expr1() expr2 := zero_double_number_stmt.Expr2() this.WalkProgramCounterExpr(expr1) this.WalkProgramCounterExpr(expr2) } func (this *Walker) WalkZeroSingleNumberStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ZERO_SINGLE_NUMBER { err := errors.New("stmt type is not a zero single number stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ZERO_SINGLE_NUMBER]; found { stmt_callback(stmt_) } zero_single_number_stmt := stmt_.ZeroSingleNumberStmt() expr_ := zero_single_number_stmt.Expr() this.WalkProgramCounterExpr(expr_) } func (this *Walker) WalkCiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CI { err := errors.New("stmt type is not a CI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CI]; found { stmt_callback(stmt_) } ci_stmt := stmt_.CiStmt() pc := ci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkDdciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DDCI { err := errors.New("stmt type is not a DDCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DDCI]; found { stmt_callback(stmt_) } ddci_stmt := stmt_.DdciStmt() pc := ddci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkDmaRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DMA_RRI { err := errors.New("stmt type is not a DMA_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DMA_RRI]; found { stmt_callback(stmt_) } dma_rri_stmt := stmt_.DmaRriStmt() imm := dma_rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkDrdiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DRDICI { err := errors.New("stmt type is not a DRDICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DRDICI]; found { stmt_callback(stmt_) } drdici_stmt := stmt_.DrdiciStmt() imm := drdici_stmt.Imm() pc := drdici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkEdriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.EDRI { err := errors.New("stmt type is not an EDRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.EDRI]; found { stmt_callback(stmt_) } edri_stmt := stmt_.EdriStmt() off := edri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkEridStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERID { err := errors.New("stmt type is not an ERID stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERID]; found { stmt_callback(stmt_) } erid_stmt := stmt_.EridStmt() off := erid_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkEriiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERII { err := errors.New("stmt type is not an ERII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERII]; found { stmt_callback(stmt_) } erii_stmt := stmt_.EriiStmt() off := erii_stmt.Off() imm := erii_stmt.Imm() this.WalkProgramCounterExpr(off) this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkErirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERIR { err := errors.New("stmt type is not an ERIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERIR]; found { stmt_callback(stmt_) } erir_stmt := stmt_.ErirStmt() off := erir_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkErriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.ERRI { err := errors.New("stmt type is not an ERRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.ERRI]; found { stmt_callback(stmt_) } erri_stmt := stmt_.ErriStmt() off := erri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkIStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.I { err := errors.New("stmt type is not an I stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.I]; found { stmt_callback(stmt_) } i_stmt := stmt_.IStmt() imm := i_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkNopStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.NOP { err := errors.New("stmt type is not a NOP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.NOP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RCI { err := errors.New("stmt type is not an RCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RCI]; found { stmt_callback(stmt_) } rci_stmt := stmt_.RciStmt() pc := rci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RICI { err := errors.New("stmt type is not an RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RICI]; found { stmt_callback(stmt_) } rici_stmt := stmt_.RiciStmt() imm := rici_stmt.Imm() pc := rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRirciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIRCI { err := errors.New("stmt type is not an RIRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIRCI]; found { stmt_callback(stmt_) } rirci_stmt := stmt_.RirciStmt() imm := rirci_stmt.Imm() pc := rirci_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRircStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIRC { err := errors.New("stmt type is not an RIRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIRC]; found { stmt_callback(stmt_) } rirc_stmt := stmt_.RircStmt() imm := rirc_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RIR { err := errors.New("stmt type is not an RIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RIR]; found { stmt_callback(stmt_) } rir_stmt := stmt_.RirStmt() imm := rir_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRCI { err := errors.New("stmt type is not an RRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRCI]; found { stmt_callback(stmt_) } rrci_stmt := stmt_.RrciStmt() pc := rrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRC { err := errors.New("stmt type is not an RRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRICI { err := errors.New("stmt type is not an RRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRICI]; found { stmt_callback(stmt_) } rrici_stmt := stmt_.RriciStmt() imm := rrici_stmt.Imm() pc := rrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRricStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRIC { err := errors.New("stmt type is not an RRIC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRIC]; found { stmt_callback(stmt_) } rric_stmt := stmt_.RricStmt() imm := rric_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRI { err := errors.New("stmt type is not an RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRI]; found { stmt_callback(stmt_) } rri_stmt := stmt_.RriStmt() imm := rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRCI { err := errors.New("stmt type is not an RRRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRCI]; found { stmt_callback(stmt_) } rrrci_stmt := stmt_.RrrciStmt() pc := rrrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRC { err := errors.New("stmt type is not an RRRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRrriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRICI { err := errors.New("stmt type is not an RRRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRICI]; found { stmt_callback(stmt_) } rrrici_stmt := stmt_.RrriciStmt() imm := rrrici_stmt.Imm() pc := rrrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkRrriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRRI { err := errors.New("stmt type is not an RRRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRI]; found { stmt_callback(stmt_) } rrri_stmt := stmt_.RrriStmt() imm := rrri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkRrrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RRR { err := errors.New("stmt type is not an RRR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.RR { err := errors.New("stmt type is not an RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.R { err := errors.New("stmt type is not an R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSErriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_ERRI { err := errors.New("stmt type is not a S_ERRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_ERRI]; found { stmt_callback(stmt_) } s_erri_stmt := stmt_.SErriStmt() off := s_erri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSRciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RCI { err := errors.New("stmt type is not a S_RCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RCI]; found { stmt_callback(stmt_) } s_rci_stmt := stmt_.SRciStmt() pc := s_rci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRirciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RIRCI { err := errors.New("stmt type is not a S_RIRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RIRCI]; found { stmt_callback(stmt_) } s_rirci_stmt := stmt_.SRirciStmt() imm := s_rirci_stmt.Imm() pc := s_rirci_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRircStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RIRC { err := errors.New("stmt type is not a S_RIRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RIRC]; found { stmt_callback(stmt_) } s_rirc_stmt := stmt_.SRircStmt() imm := s_rirc_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRCI { err := errors.New("stmt type is not a S_RRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRCI]; found { stmt_callback(stmt_) } s_rrci_stmt := stmt_.SRrciStmt() pc := s_rrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRC { err := errors.New("stmt type is not a S_RRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRICI { err := errors.New("stmt type is not a S_RRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRICI]; found { stmt_callback(stmt_) } s_rrici_stmt := stmt_.SRriciStmt() imm := s_rrici_stmt.Imm() pc := s_rrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRricStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRIC { err := errors.New("stmt type is not a S_RRIC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRIC]; found { stmt_callback(stmt_) } s_rric_stmt := stmt_.SRricStmt() imm := s_rric_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRI { err := errors.New("stmt type is not a S_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRI]; found { stmt_callback(stmt_) } s_rri_stmt := stmt_.SRriStmt() imm := s_rri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrrciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRCI { err := errors.New("stmt type is not an S_RRRCI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRCI]; found { stmt_callback(stmt_) } s_rrrci_stmt := stmt_.SRrrciStmt() pc := s_rrrci_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrrcStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRC { err := errors.New("stmt type is not an S_RRRC stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.RRRC]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRrriciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRICI { err := errors.New("stmt type is not a S_RRRICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRICI]; found { stmt_callback(stmt_) } s_rrrici_stmt := stmt_.SRrriciStmt() imm := s_rrrici_stmt.Imm() pc := s_rrrici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkSRrriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRRI { err := errors.New("stmt type is not a S_RRRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRRI]; found { stmt_callback(stmt_) } s_rrri_stmt := stmt_.SRrriStmt() imm := s_rrri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSRrrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RRR { err := errors.New("stmt type is not a RRR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RRR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_RR { err := errors.New("stmt type is not a S_RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkSRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.S_R { err := errors.New("stmt type is not a S_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.S_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkBkpStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BKP { err := errors.New("stmt type is not a BKP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BKP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkBootRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.BOOT_RI { err := errors.New("stmt type is not a BOOT_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.BOOT_RI]; found { stmt_callback(stmt_) } boot_ri_stmt := stmt_.BootRiStmt() imm := boot_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkCallRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CALL_RI { err := errors.New("stmt type is not a CALL_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CALL_RI]; found { stmt_callback(stmt_) } call_ri_stmt := stmt_.CallRiStmt() imm := call_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkCallRrStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.CALL_RR { err := errors.New("stmt type is not a CALL_RR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.CALL_RR]; found { stmt_callback(stmt_) } } func (this *Walker) WalkDivStepDrdiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.DIV_STEP_DRDI { err := errors.New("stmt type is not a DIV_STEP_DRDI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.DIV_STEP_DRDI]; found { stmt_callback(stmt_) } div_step_drdi_stmt := stmt_.DivStepDrdiStmt() imm := div_step_drdi_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkJeqRiiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JEQ_RII { err := errors.New("stmt type is not a JEQ_RII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JEQ_RII]; found { stmt_callback(stmt_) } jeq_rii_stmt := stmt_.JeqRiiStmt() imm := jeq_rii_stmt.Imm() pc := jeq_rii_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJeqRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JEQ_RRI { err := errors.New("stmt type is not a JEQ_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JEQ_RRI]; found { stmt_callback(stmt_) } jeq_rri_stmt := stmt_.JeqRriStmt() pc := jeq_rri_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJnzRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JNZ_RI { err := errors.New("stmt type is not a JNZ_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JNZ_RI]; found { stmt_callback(stmt_) } jnz_ri_stmt := stmt_.JnzRiStmt() pc := jnz_ri_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJumpIStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JUMP_I { err := errors.New("stmt type is not a JUMP_I stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JUMP_I]; found { stmt_callback(stmt_) } jump_i_stmt := stmt_.JumpIStmt() pc := jump_i_stmt.Pc() this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkJumpRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.JUMP_R { err := errors.New("stmt type is not a JUMP_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.JUMP_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkLbsRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LBS_RRI { err := errors.New("stmt type is not a LBS_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LBS_RRI]; found { stmt_callback(stmt_) } lbs_rri_stmt := stmt_.LbsRriStmt() off := lbs_rri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkLbsSRriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LBS_S_RRI { err := errors.New("stmt type is not a LBS_S_RRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LBS_S_RRI]; found { stmt_callback(stmt_) } lbs_s_rri_stmt := stmt_.LbsSRriStmt() off := lbs_s_rri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkLdDriStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LD_DRI { err := errors.New("stmt type is not a LD_DRI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LD_DRI]; found { stmt_callback(stmt_) } ld_dri_stmt := stmt_.LdDriStmt() off := ld_dri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkMovdDdStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVD_DD { err := errors.New("stmt type is not a MOVD_DD stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVD_DD]; found { stmt_callback(stmt_) } } func (this *Walker) WalkMoveRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_RICI { err := errors.New("stmt type is not a MOVE_RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_RICI]; found { stmt_callback(stmt_) } move_rici_stmt := stmt_.MoveRiciStmt() imm := move_rici_stmt.Imm() pc := move_rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkMoveRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_RI { err := errors.New("stmt type is not a MOVE_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_RI]; found { stmt_callback(stmt_) } move_ri_stmt := stmt_.MoveRiStmt() imm := move_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkMoveSRiciStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_S_RICI { err := errors.New("stmt type is not a MOVE_S_RICI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_S_RICI]; found { stmt_callback(stmt_) } move_s_rici_stmt := stmt_.MoveSRiciStmt() imm := move_s_rici_stmt.Imm() pc := move_s_rici_stmt.Pc() this.WalkProgramCounterExpr(imm) this.WalkProgramCounterExpr(pc) } func (this *Walker) WalkMoveSRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.MOVE_S_RI { err := errors.New("stmt type is not a MOVE_S_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.MOVE_S_RI]; found { stmt_callback(stmt_) } move_s_ri_stmt := stmt_.MoveSRiStmt() imm := move_s_ri_stmt.Imm() this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSbIdRiiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_ID_RII { err := errors.New("stmt type is not a SB_ID_RII stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_ID_RII]; found { stmt_callback(stmt_) } sb_id_rii_stmt := stmt_.SbIdRiiStmt() off := sb_id_rii_stmt.Off() imm := sb_id_rii_stmt.Imm() this.WalkProgramCounterExpr(off) this.WalkProgramCounterExpr(imm) } func (this *Walker) WalkSbIdRiStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_ID_RI { err := errors.New("stmt type is not a SB_ID_RI stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_ID_RI]; found { stmt_callback(stmt_) } sb_id_ri_stmt := stmt_.SbIdRiStmt() off := sb_id_ri_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSbRirStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SB_RIR { err := errors.New("stmt type is not a SB_RIR stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SB_RIR]; found { stmt_callback(stmt_) } sb_rir_stmt := stmt_.SbRirStmt() off := sb_rir_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkSdRidStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.SD_RID { err := errors.New("stmt type is not a SD_RID stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.SD_RID]; found { stmt_callback(stmt_) } sd_rid_stmt := stmt_.SdRidStmt() off := sd_rid_stmt.Off() this.WalkProgramCounterExpr(off) } func (this *Walker) WalkStopStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.STOP { err := errors.New("stmt type is not a STOP stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.STOP]; found { stmt_callback(stmt_) } } func (this *Walker) WalkTimeCfgRStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.TIME_CFG_R { err := errors.New("stmt type is not a TIME_CFG_R stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.TIME_CFG_R]; found { stmt_callback(stmt_) } } func (this *Walker) WalkLabelStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() != stmt.LABEL { err := errors.New("stmt type is not a LABEL stmt") panic(err) } if stmt_callback, found := this.stmt_callbacks[stmt.LABEL]; found { stmt_callback(stmt_) } label_stmt := stmt_.LabelStmt() expr_ := label_stmt.Expr() this.WalkProgramCounterExpr(expr_) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/channel/channel.go ================================================ package channel import ( "errors" "uPIMulator/src/device/simulator/dpu" "uPIMulator/src/device/simulator/rank" "uPIMulator/src/misc" ) type Channel struct { channel_id int ranks []*rank.Rank input_q *ChannelCommandQ ready_q *ChannelCommandQ scoreboard map[*rank.RankCommand]*ChannelCommand } func (this *Channel) Init(channel_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } this.channel_id = channel_id this.ranks = make([]*rank.Rank, 0) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) for i := 0; i < num_ranks_per_channel; i++ { rank_ := new(rank.Rank) rank_.Init(channel_id, i, command_line_parser) this.ranks = append(this.ranks, rank_) } this.input_q = new(ChannelCommandQ) this.input_q.Init(-1, 0) this.ready_q = new(ChannelCommandQ) this.ready_q.Init(-1, 0) this.scoreboard = make(map[*rank.RankCommand]*ChannelCommand) } func (this *Channel) Fini() { for _, rank_ := range this.ranks { rank_.Fini() } this.input_q.Fini() this.ready_q.Fini() } func (this *Channel) ChannelId() int { return this.channel_id } func (this *Channel) NumRanks() int { return len(this.ranks) } func (this *Channel) Ranks() []*rank.Rank { return this.ranks } func (this *Channel) Dpus() []*dpu.Dpu { dpus := make([]*dpu.Dpu, 0) for _, rank_ := range this.ranks { dpus = append(dpus, rank_.Dpus()...) } return dpus } func (this *Channel) CanPush() bool { return this.input_q.CanPush(1) } func (this *Channel) Push(channel_command *ChannelCommand) { if !this.CanPush() { err := errors.New("channel cannot be pushed") panic(err) } this.input_q.Push(channel_command) } func (this *Channel) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Channel) Pop() *ChannelCommand { if !this.CanPop() { err := errors.New("channel cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Channel) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() for _, rank_ := range this.ranks { rank_.Cycle() } this.input_q.Cycle() this.ready_q.Cycle() } func (this *Channel) ServiceInputQ() { if this.input_q.CanPop(1) { channel_command, _ := this.input_q.Front(0) rank_id := channel_command.RankId() if this.ranks[rank_id].CanPush() { this.input_q.Pop() rank_command := channel_command.RankCommand() this.ranks[rank_id].Push(rank_command) this.scoreboard[rank_command] = channel_command } } } func (this *Channel) ServiceReadyQ() { for _, rank_ := range this.ranks { if rank_.CanPop() && this.ready_q.CanPush(1) { rank_command := rank_.Pop() channel_command := this.scoreboard[rank_command] this.ready_q.Push(channel_command) delete(this.scoreboard, rank_command) } } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/channel/channel_command.go ================================================ package channel import ( "errors" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/device/simulator/rank" ) type ChannelCommand struct { channel_id int rank_id int dpu_id int rank_command *rank.RankCommand dma_command *dram.DmaCommand } func (this *ChannelCommand) Init( channel_id int, rank_id int, dpu_id int, dma_command *dram.DmaCommand, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.rank_command = new(rank.RankCommand) this.rank_command.Init(channel_id, rank_id, dpu_id, dma_command) this.dma_command = dma_command } func (this *ChannelCommand) ChannelId() int { return this.channel_id } func (this *ChannelCommand) RankId() int { return this.rank_id } func (this *ChannelCommand) DpuId() int { return this.dpu_id } func (this *ChannelCommand) RankCommand() *rank.RankCommand { return this.rank_command } func (this *ChannelCommand) DmaCommand() *dram.DmaCommand { return this.dma_command } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/channel/channel_command_q.go ================================================ package channel import ( "errors" ) type ChannelCommandQ struct { size int timer int64 channel_commands []*ChannelCommand cycles []int64 } func (this *ChannelCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.channel_commands = make([]*ChannelCommand, 0) this.cycles = make([]int64, 0) } func (this *ChannelCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("channel command queue is not empty") panic(err) } } func (this *ChannelCommandQ) Size() int { return this.size } func (this *ChannelCommandQ) Length() int { return len(this.channel_commands) } func (this *ChannelCommandQ) Timer() int64 { return this.timer } func (this *ChannelCommandQ) IsEmpty() bool { return len(this.channel_commands) == 0 } func (this *ChannelCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.channel_commands) >= num_items } else { return true } } func (this *ChannelCommandQ) Push(channel_command *ChannelCommand) { if !this.CanPush(1) { err := errors.New("channel command queue cannot be pushed") panic(err) } this.channel_commands = append(this.channel_commands, channel_command) this.cycles = append(this.cycles, this.timer) } func (this *ChannelCommandQ) PushWithTimer(channel_command *ChannelCommand, timer int64) { if !this.CanPush(1) { err := errors.New("channel command queue cannot be pushed") panic(err) } this.channel_commands = append(this.channel_commands, channel_command) this.cycles = append(this.cycles, timer) } func (this *ChannelCommandQ) CanPop(num_items int) bool { if len(this.channel_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *ChannelCommandQ) Pop() *ChannelCommand { if !this.CanPop(1) { err := errors.New("channel command queue cannot be popped") panic(err) } channel_command := this.channel_commands[0] this.channel_commands = this.channel_commands[1:] this.cycles = this.cycles[1:] return channel_command } func (this *ChannelCommandQ) Front(pos int) (*ChannelCommand, int64) { return this.channel_commands[pos], this.cycles[pos] } func (this *ChannelCommandQ) Remove(pos int) { this.channel_commands = append(this.channel_commands[:pos], this.channel_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *ChannelCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/control_interface.go ================================================ package dpu import ( "errors" ) type ControlInterface struct { boot bool } func (this *ControlInterface) Init() { this.boot = false } func (this *ControlInterface) Boot() bool { return this.boot } func (this *ControlInterface) SetBoot() { if this.boot { err := errors.New("control interface is already booted") panic(err) } this.boot = true } func (this *ControlInterface) UnsetBoot() { if !this.boot { err := errors.New("control interface is not booted") panic(err) } this.boot = false } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dpu.go ================================================ package dpu import ( "errors" "fmt" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/device/simulator/dpu/logic" "uPIMulator/src/device/simulator/dpu/sram" "uPIMulator/src/misc" ) type Dpu struct { channel_id int rank_id int dpu_id int logic_frequency int64 memory_frequency int64 frequency_ratio float64 cycles int64 control_interface *ControlInterface threads []*logic.Thread thread_scheduler *logic.ThreadScheduler atomic *sram.Atomic iram *sram.Iram wram *sram.Wram mram *dram.Mram operand_collector *logic.OperandCollector memory_controller *dram.MemoryController dma *logic.Dma logic *logic.Logic stat_factory *misc.StatFactory } func (this *Dpu) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.logic_frequency = command_line_parser.IntParameter("logic_frequency") this.memory_frequency = command_line_parser.IntParameter("memory_frequency") this.frequency_ratio = float64(this.memory_frequency) / float64(this.logic_frequency) this.cycles = 0 this.control_interface = new(ControlInterface) this.control_interface.Init() this.threads = make([]*logic.Thread, 0) num_threads := int(command_line_parser.IntParameter("num_tasklets")) for i := 0; i < num_threads; i++ { thread := new(logic.Thread) thread.Init(i) this.threads = append(this.threads, thread) } this.thread_scheduler = new(logic.ThreadScheduler) this.thread_scheduler.Init(channel_id, rank_id, dpu_id, this.threads, command_line_parser) this.atomic = new(sram.Atomic) this.atomic.Init() this.iram = new(sram.Iram) this.iram.Init() this.wram = new(sram.Wram) this.wram.Init() this.mram = new(dram.Mram) this.mram.Init(command_line_parser) this.operand_collector = new(logic.OperandCollector) this.operand_collector.Init() this.operand_collector.ConnectWram(this.wram) this.memory_controller = new(dram.MemoryController) this.memory_controller.Init(channel_id, rank_id, dpu_id, command_line_parser) this.memory_controller.ConnectMram(this.mram) this.dma = new(logic.Dma) this.dma.Init() this.dma.ConnectAtomic(this.atomic) this.dma.ConnectIram(this.iram) this.dma.ConnectOperandCollector(this.operand_collector) this.dma.ConnectMemoryController(this.memory_controller) this.logic = new(logic.Logic) this.logic.Init(channel_id, rank_id, dpu_id, command_line_parser) this.logic.ConnectThreadScheduler(this.thread_scheduler) this.logic.ConnectAtomic(this.atomic) this.logic.ConnectIram(this.iram) this.logic.ConnectOperandCollector(this.operand_collector) this.logic.ConnectDma(this.dma) name := fmt.Sprintf("DPU%d-%d-%d", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *Dpu) Fini() { for _, thread := range this.threads { thread.Fini() } this.atomic.Fini() this.iram.Fini() this.wram.Fini() this.mram.Fini() this.operand_collector.Fini() this.memory_controller.Fini() this.logic.Fini() this.dma.Fini() } func (this *Dpu) ChannelId() int { return this.channel_id } func (this *Dpu) RankId() int { return this.rank_id } func (this *Dpu) DpuId() int { return this.dpu_id } func (this *Dpu) ThreadScheduler() *logic.ThreadScheduler { return this.thread_scheduler } func (this *Dpu) Logic() *logic.Logic { return this.logic } func (this *Dpu) MemoryController() *dram.MemoryController { return this.memory_controller } func (this *Dpu) Dma() *logic.Dma { return this.dma } func (this *Dpu) Threads() []*logic.Thread { return this.threads } func (this *Dpu) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *Dpu) Boot() { this.control_interface.SetBoot() this.thread_scheduler.Boot(0) } func (this *Dpu) Unboot() { this.control_interface.UnsetBoot() this.thread_scheduler.Unboot() } func (this *Dpu) IsZombie() bool { for _, thread := range this.threads { if thread.ThreadState() != logic.ZOMBIE { return false } } return this.logic.IsEmpty() && this.memory_controller.IsEmpty() } func (this *Dpu) Cycle() { this.dma.Cycle() num_memory_cycles := int( this.frequency_ratio*float64(this.cycles) - this.frequency_ratio*float64(this.cycles-1), ) for i := 0; i < num_memory_cycles; i++ { this.memory_controller.Cycle() } if this.control_interface.Boot() { for _, thread := range this.threads { thread.IncrementIssueCycle() } this.thread_scheduler.Cycle() this.logic.Cycle() } this.cycles++ } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/dma_command.go ================================================ package dram import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/encoding" ) type DmaCommand struct { memory_operation MemoryOperation wram_address *int64 mram_address *int64 size int64 byte_stream *encoding.ByteStream acks []bool instruction *instruction.Instruction } func (this *DmaCommand) InitReadFromMram(mram_address int64, size int64) { this.memory_operation = READ this.wram_address = nil this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.byte_stream.Append(0) this.acks = append(this.acks, false) } this.instruction = nil } func (this *DmaCommand) InitWriteToMram( mram_address int64, size int64, byte_stream *encoding.ByteStream, ) { this.memory_operation = WRITE this.wram_address = nil this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = byte_stream this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = nil } func (this *DmaCommand) InitReadFromMramToWram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if instruction_.OpCode() != instruction.LDMA { err := errors.New("instruction's op code != LDMA") panic(err) } this.memory_operation = READ this.wram_address = new(int64) *this.wram_address = wram_address this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = instruction_ } func (this *DmaCommand) InitWriteToMramFromWram( wram_address int64, mram_address int64, size int64, byte_stream *encoding.ByteStream, instruction_ *instruction.Instruction, ) { if instruction_.OpCode() != instruction.SDMA { err := errors.New("instruction's op code != SDMA") panic(err) } this.memory_operation = WRITE this.wram_address = new(int64) *this.wram_address = wram_address this.mram_address = new(int64) *this.mram_address = mram_address this.size = size this.byte_stream = byte_stream this.acks = make([]bool, 0) for i := int64(0); i < size; i++ { this.acks = append(this.acks, false) } this.instruction = instruction_ } func (this *DmaCommand) Fini() { if !this.IsReady() { err := errors.New("DMA command is not ready") panic(err) } } func (this *DmaCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *DmaCommand) WramAddress() int64 { if this.wram_address == nil { err := errors.New("DMA command does not have a WRAM address") panic(err) } return *this.wram_address } func (this *DmaCommand) MramAddress() int64 { if this.mram_address == nil { err := errors.New("DMA command does not have an MRAM address") panic(err) } return *this.mram_address } func (this *DmaCommand) Size() int64 { return this.size } func (this *DmaCommand) HasInstruction() bool { return this.instruction != nil } func (this *DmaCommand) Instruction() *instruction.Instruction { return this.instruction } func (this *DmaCommand) ByteStream(mram_address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(mram_address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } return byte_stream } func (this *DmaCommand) SetByteStream( mram_address int64, size int64, byte_stream *encoding.ByteStream, ) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(mram_address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *DmaCommand) SetAck(mram_address int64, size int64) { for i := int64(0); i < size; i++ { index := this.Index(mram_address) + int(i) if this.acks[index] { err := errors.New("ACK is already set") panic(err) } this.acks[index] = true } } func (this *DmaCommand) IsReady() bool { for _, ack := range this.acks { if !ack { return false } } return true } func (this *DmaCommand) Index(mram_address int64) int { if mram_address < this.MramAddress() { err := errors.New("MRAM address < DMA command's MRAM address") panic(err) } else if mram_address >= this.MramAddress()+this.Size() { err := errors.New("MRAM address >= DMA command's MRAM address + DMA command's size") panic(err) } return int(mram_address - this.MramAddress()) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/dma_command_q.go ================================================ package dram import ( "errors" ) type DmaCommandQ struct { size int timer int64 dma_commands []*DmaCommand cycles []int64 } func (this *DmaCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.dma_commands = make([]*DmaCommand, 0) this.cycles = make([]int64, 0) } func (this *DmaCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("DMA command queue is not empty") panic(err) } } func (this *DmaCommandQ) Size() int { return this.size } func (this *DmaCommandQ) Length() int { return len(this.dma_commands) } func (this *DmaCommandQ) Timer() int64 { return this.timer } func (this *DmaCommandQ) IsEmpty() bool { return len(this.dma_commands) == 0 } func (this *DmaCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.dma_commands) >= num_items } else { return true } } func (this *DmaCommandQ) Push(dma_command *DmaCommand) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, this.timer) } func (this *DmaCommandQ) PushWithTimer(dma_command *DmaCommand, timer int64) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, timer) } func (this *DmaCommandQ) CanPop(num_items int) bool { if len(this.dma_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *DmaCommandQ) Pop() *DmaCommand { if !this.CanPop(1) { err := errors.New("DMA command queue cannot be popped") panic(err) } dma_command := this.dma_commands[0] this.dma_commands = this.dma_commands[1:] this.cycles = this.cycles[1:] return dma_command } func (this *DmaCommandQ) Front(pos int) (*DmaCommand, int64) { return this.dma_commands[pos], this.cycles[pos] } func (this *DmaCommandQ) Remove(pos int) { this.dma_commands = append(this.dma_commands[:pos], this.dma_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *DmaCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/memory_command.go ================================================ package dram import ( "errors" "uPIMulator/src/encoding" ) type MemoryOperation int const ( ACTIVATION MemoryOperation = iota READ WRITE PRECHARGE ) type MemoryCommand struct { memory_operation MemoryOperation address int64 size int64 byte_stream *encoding.ByteStream dma_command *DmaCommand } func (this *MemoryCommand) InitActivation(memory_operation MemoryOperation, address int64) { this.memory_operation = memory_operation this.address = address this.size = 0 this.byte_stream = nil this.dma_command = nil } func (this *MemoryCommand) InitRead( memory_operation MemoryOperation, address int64, size int64, dma_command *DmaCommand, ) { if memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } else if dma_command.MemoryOperation() != READ { err := errors.New("DMA operation != READ") panic(err) } this.memory_operation = memory_operation this.address = address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.dma_command = dma_command } func (this *MemoryCommand) InitWrite( memory_operation MemoryOperation, address int64, size int64, byte_stream *encoding.ByteStream, dma_command *DmaCommand, ) { if memory_operation != WRITE { err := errors.New("memory operation != WRITE") panic(err) } else if dma_command.MemoryOperation() != WRITE { err := errors.New("DMA operation != WRITE") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } this.memory_operation = memory_operation this.address = address this.size = size this.byte_stream = byte_stream this.dma_command = dma_command } func (this *MemoryCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *MemoryCommand) Address() int64 { return this.address } func (this *MemoryCommand) Size() int64 { return this.size } func (this *MemoryCommand) ByteStream() *encoding.ByteStream { if this.byte_stream == nil { err := errors.New("byte stream == nil") panic(err) } return this.byte_stream } func (this *MemoryCommand) SetByteStream(byte_stream *encoding.ByteStream) { if this.memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } func (this *MemoryCommand) DmaCommand() *DmaCommand { if this.dma_command == nil { err := errors.New("DMA command == nil") panic(err) } return this.dma_command } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/memory_command_q.go ================================================ package dram import ( "errors" ) type MemoryCommandQ struct { size int timer int64 memory_commands []*MemoryCommand cycles []int64 } func (this *MemoryCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.memory_commands = make([]*MemoryCommand, 0) this.cycles = make([]int64, 0) } func (this *MemoryCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("memory command queue is not empty") panic(err) } } func (this *MemoryCommandQ) Size() int { return this.size } func (this *MemoryCommandQ) Length() int { return len(this.memory_commands) } func (this *MemoryCommandQ) Timer() int64 { return this.timer } func (this *MemoryCommandQ) IsEmpty() bool { return len(this.memory_commands) == 0 } func (this *MemoryCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.memory_commands) >= num_items } else { return true } } func (this *MemoryCommandQ) Push(memory_command *MemoryCommand) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, this.timer) } func (this *MemoryCommandQ) PushWithTimer(memory_command *MemoryCommand, timer int64) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, timer) } func (this *MemoryCommandQ) CanPop(num_items int) bool { if len(this.memory_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *MemoryCommandQ) Pop() *MemoryCommand { if !this.CanPop(1) { err := errors.New("memory command queue cannot be popped") panic(err) } memory_command := this.memory_commands[0] this.memory_commands = this.memory_commands[1:] this.cycles = this.cycles[1:] return memory_command } func (this *MemoryCommandQ) Front(pos int) (*MemoryCommand, int64) { return this.memory_commands[pos], this.cycles[pos] } func (this *MemoryCommandQ) Remove(pos int) { this.memory_commands = append(this.memory_commands[:pos], this.memory_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *MemoryCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/memory_controller.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type MemoryController struct { channel_id int rank_id int dpu_id int wordline_size int64 memory_scheduler *MemoryScheduler row_buffer *RowBuffer mram *Mram input_q *DmaCommandQ wait_q *DmaCommandQ memory_command_q *MemoryCommandQ ready_q *DmaCommandQ stat_factory *misc.StatFactory } func (this *MemoryController) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.wordline_size = command_line_parser.IntParameter("wordline_size") this.memory_scheduler = new(MemoryScheduler) this.memory_scheduler.Init(channel_id, rank_id, dpu_id, command_line_parser) this.row_buffer = new(RowBuffer) this.row_buffer.Init(channel_id, rank_id, dpu_id, command_line_parser) this.mram = nil this.input_q = new(DmaCommandQ) this.input_q.Init(-1, 0) this.wait_q = new(DmaCommandQ) this.wait_q.Init(-1, 0) this.memory_command_q = new(MemoryCommandQ) this.memory_command_q.Init(-1, 0) this.ready_q = new(DmaCommandQ) this.ready_q.Init(-1, 0) name := fmt.Sprintf("MemoryController[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *MemoryController) Fini() { this.memory_scheduler.Fini() this.row_buffer.Fini() this.input_q.Fini() this.wait_q.Fini() this.memory_command_q.Fini() this.ready_q.Fini() } func (this *MemoryController) ConnectMram(mram *Mram) { if this.mram != nil { err := errors.New("MRAM is already set") panic(err) } this.mram = mram this.row_buffer.ConnectMram(mram) } func (this *MemoryController) MemoryScheduler() *MemoryScheduler { return this.memory_scheduler } func (this *MemoryController) RowBuffer() *RowBuffer { return this.row_buffer } func (this *MemoryController) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *MemoryController) IsEmpty() bool { return this.memory_scheduler.IsEmpty() && this.row_buffer.IsEmpty() && this.input_q.IsEmpty() && this.wait_q.IsEmpty() && this.memory_command_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *MemoryController) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryController) Push(dma_command *DmaCommand) { if !this.CanPush() { err := errors.New("memory controller cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *MemoryController) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryController) Pop() *DmaCommand { if !this.CanPop() { err := errors.New("memory controller cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryController) Read(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.mram.Read(cur_wordline_address) for i := cur_offset; i < cur_offset+cur_size; i++ { byte_stream.Append(mram_byte_stream.Get(int(i))) } cur_address += cur_size } return byte_stream } func (this *MemoryController) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } cur_byte_stream_offset := int64(0) for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.mram.Read(cur_wordline_address) for i := int64(0); i < cur_size; i++ { mram_byte_stream.Set(int(i+cur_offset), byte_stream.Get(int(i+cur_byte_stream_offset))) } this.mram.Write(cur_wordline_address, mram_byte_stream.Size(), mram_byte_stream) cur_address += cur_size cur_byte_stream_offset += cur_size } } func (this *MemoryController) Flush() { this.memory_scheduler.Flush() this.row_buffer.Flush() } func (this *MemoryController) Cycle() { this.ServiceInputQ() this.ServiceScheduler() this.ServiceMemoryCommandQ() this.ServiceRowBuffer() this.ServiceWaitQ() this.memory_scheduler.Cycle() this.row_buffer.Cycle() this.input_q.Cycle() this.wait_q.Cycle() this.memory_command_q.Cycle() this.ready_q.Cycle() this.stat_factory.Increment("memory_cycle", 1) } func (this *MemoryController) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) && this.memory_scheduler.CanPush() { dma_command := this.input_q.Pop() this.memory_scheduler.Push(dma_command) this.wait_q.Push(dma_command) } } func (this *MemoryController) ServiceScheduler() { if this.memory_scheduler.CanPop() && this.memory_command_q.CanPush(1) { memory_command := this.memory_scheduler.Pop() this.memory_command_q.Push(memory_command) } } func (this *MemoryController) ServiceMemoryCommandQ() { if this.memory_command_q.CanPop(1) && this.row_buffer.CanPush() { memory_command := this.memory_command_q.Pop() this.row_buffer.Push(memory_command) } } func (this *MemoryController) ServiceRowBuffer() { if this.row_buffer.CanPop() { memory_command := this.row_buffer.Pop() memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { return } else if memory_operation == PRECHARGE { return } else if memory_operation == READ { address := memory_command.Address() size := memory_command.Size() byte_stream := memory_command.ByteStream() dma_command := memory_command.DmaCommand() dma_command.SetByteStream(address, size, byte_stream) dma_command.SetAck(address, size) } else if memory_operation == WRITE { address := memory_command.Address() size := memory_command.Size() dma_command := memory_command.DmaCommand() dma_command.SetAck(address, size) } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *MemoryController) ServiceWaitQ() { for i := 0; this.wait_q.CanPop(i + 1); i++ { dma_command, _ := this.wait_q.Front(i) if dma_command.IsReady() && this.ready_q.CanPush(1) { this.wait_q.Remove(i) this.ready_q.Push(dma_command) } } } func (this *MemoryController) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *MemoryController) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/memory_scheduler.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/misc" ) type MemoryScheduler struct { channel_id int rank_id int dpu_id int input_q *DmaCommandQ reorder_buffer *MemoryCommandQ ready_q *MemoryCommandQ row_address *int64 wordline_size int64 min_access_granularity int64 reorder_window_size int stat_factory *misc.StatFactory } func (this *MemoryScheduler) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.input_q = new(DmaCommandQ) this.input_q.Init(-1, 0) this.reorder_buffer = new(MemoryCommandQ) this.reorder_buffer.Init(-1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) this.row_address = nil this.wordline_size = command_line_parser.IntParameter("wordline_size") this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.reorder_window_size = int(command_line_parser.IntParameter("reorder_window_size")) name := fmt.Sprintf("MemoryScheduler[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *MemoryScheduler) Fini() { this.input_q.Fini() this.reorder_buffer.Fini() this.ready_q.Fini() } func (this *MemoryScheduler) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *MemoryScheduler) IsEmpty() bool { return this.input_q.IsEmpty() && this.reorder_buffer.IsEmpty() && this.ready_q.IsEmpty() } func (this *MemoryScheduler) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryScheduler) Push(dma_command *DmaCommand) { if !this.CanPush() { err := errors.New("memory scheduler cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *MemoryScheduler) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryScheduler) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("memory scheduler cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryScheduler) Flush() { if !this.IsEmpty() { err := errors.New("memory scheduler cannot be flushed") panic(err) } this.row_address = nil } func (this *MemoryScheduler) Cycle() { this.ServiceInputQ() if !this.ReorderFr() { this.ReorderFcFs() } this.input_q.Cycle() this.reorder_buffer.Cycle() this.ready_q.Cycle() } func (this *MemoryScheduler) ServiceInputQ() { if this.input_q.CanPop(1) { dma_command := this.input_q.Pop() this.PopulateMemoryCommands(dma_command) } } func (this *MemoryScheduler) PopulateMemoryCommands(dma_command *DmaCommand) { begin_address := dma_command.MramAddress() end_address := dma_command.MramAddress() + dma_command.Size() for address := begin_address; address < end_address; { wordline_address := this.WordlineAddress(address) size := this.Min( this.Min( address+this.min_access_granularity, wordline_address+this.wordline_size, ), end_address, ) - address memory_operation := dma_command.MemoryOperation() memory_command := new(MemoryCommand) if memory_operation == READ { memory_command.InitRead(READ, address, size, dma_command) } else if memory_operation == WRITE { byte_stream := dma_command.ByteStream(address, size) memory_command.InitWrite(WRITE, address, size, byte_stream, dma_command) } else { err := errors.New("memory operation is not valid") panic(err) } this.reorder_buffer.Push(memory_command) address += size } } func (this *MemoryScheduler) ReorderFr() bool { if this.row_address != nil && this.ready_q.CanPush(1) { for i := 0; this.reorder_buffer.CanPop(i+1) && i < this.reorder_window_size; i++ { memory_command, _ := this.reorder_buffer.Front(i) if this.WordlineAddress(memory_command.Address()) == *this.row_address { if i != 0 { this.stat_factory.Increment("num_fr", 1) } else { this.stat_factory.Increment("num_fcfs", 1) } this.reorder_buffer.Remove(i) this.ready_q.Push(memory_command) return true } } } return false } func (this *MemoryScheduler) ReorderFcFs() bool { if this.reorder_buffer.CanPop(1) && this.row_address != nil && this.ready_q.CanPush(3) { memory_command := this.reorder_buffer.Pop() wordline_address := this.WordlineAddress(memory_command.Address()) precharge := new(MemoryCommand) precharge.InitActivation(PRECHARGE, *this.row_address) activation := new(MemoryCommand) activation.InitActivation(ACTIVATION, wordline_address) this.ready_q.Push(precharge) this.ready_q.Push(activation) this.ready_q.Push(memory_command) *this.row_address = wordline_address return true } else if this.reorder_buffer.CanPop(1) && this.row_address == nil && this.ready_q.CanPush(2) { memory_command := this.reorder_buffer.Pop() wordline_address := this.WordlineAddress(memory_command.Address()) activation := new(MemoryCommand) activation.InitActivation(ACTIVATION, wordline_address) this.ready_q.Push(activation) this.ready_q.Push(memory_command) this.row_address = new(int64) *this.row_address = wordline_address return true } else { return false } } func (this *MemoryScheduler) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *MemoryScheduler) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/mram.go ================================================ package dram import ( "errors" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Mram struct { address int64 size int64 wordline_size int64 wordlines []*Wordline } func (this *Mram) Init(command_line_parser *misc.CommandLineParser) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.MramOffset() this.size = config_loader.MramSize() this.wordline_size = command_line_parser.IntParameter("wordline_size") if this.wordline_size <= 0 { err := errors.New("wordline size <= 0") panic(err) } else if this.address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if this.size%this.wordline_size != 0 { err := errors.New("size is not aligned with wordline size") panic(err) } this.wordlines = make([]*Wordline, 0) num_wordlines := int(this.size / this.wordline_size) for i := 0; i < num_wordlines; i++ { wordline := new(Wordline) wordline.Init(this.address+int64(i)*this.wordline_size, this.wordline_size) this.wordlines = append(this.wordlines, wordline) } } func (this *Mram) Fini() { for _, wordline := range this.wordlines { wordline.Fini() } } func (this *Mram) Address() int64 { return this.address } func (this *Mram) Size() int64 { return this.size } func (this *Mram) Read(address int64) *encoding.ByteStream { return this.wordlines[this.Index(address)].Read() } func (this *Mram) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } this.wordlines[this.Index(address)].Write(byte_stream) } func (this *Mram) Index(address int64) int { if address < this.address { err := errors.New("address < MRAM offset") panic(err) } else if address+this.wordline_size > this.address+this.size { err := errors.New("address + wordline size > MRAM offset + MRAM size") panic(err) } else if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } return int((address - this.address) / this.wordline_size) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/row_buffer.go ================================================ package dram import ( "errors" "fmt" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type RowBuffer struct { channel_id int rank_id int dpu_id int t_ras int64 t_rcd int64 t_cl int64 t_bl int64 t_rp int64 wordline_size int64 mram *Mram row_address *int64 row_buffer *encoding.ByteStream input_q *MemoryCommandQ ready_q *MemoryCommandQ activation_q *MemoryCommandQ io_q *MemoryCommandQ bus_q *MemoryCommandQ precharge_q *MemoryCommandQ stat_factory *misc.StatFactory } func (this *RowBuffer) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.t_ras = command_line_parser.IntParameter("t_ras") this.t_rcd = command_line_parser.IntParameter("t_rcd") this.t_cl = command_line_parser.IntParameter("t_cl") this.t_bl = command_line_parser.IntParameter("t_bl") this.t_rp = command_line_parser.IntParameter("t_rp") this.wordline_size = command_line_parser.IntParameter("wordline_size") this.mram = nil this.row_address = nil this.row_buffer = nil this.input_q = new(MemoryCommandQ) this.input_q.Init(1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) this.activation_q = new(MemoryCommandQ) this.activation_q.Init(1, this.t_ras) this.io_q = new(MemoryCommandQ) this.io_q.Init(1, this.t_cl) this.bus_q = new(MemoryCommandQ) this.bus_q.Init(1, this.t_bl) this.precharge_q = new(MemoryCommandQ) this.precharge_q.Init(1, this.t_rp) name := fmt.Sprintf("RowBuffer[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *RowBuffer) Fini() { this.input_q.Fini() this.ready_q.Fini() this.activation_q.Fini() this.io_q.Fini() this.bus_q.Fini() this.precharge_q.Fini() } func (this *RowBuffer) ConnectMram(mram *Mram) { if this.mram != nil { err := errors.New("MRAM is already connected") panic(err) } this.mram = mram } func (this *RowBuffer) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *RowBuffer) IsEmpty() bool { return this.input_q.IsEmpty() && this.ready_q.IsEmpty() && this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() } func (this *RowBuffer) CanPush() bool { return this.input_q.CanPush(1) } func (this *RowBuffer) Push(memory_command *MemoryCommand) { if !this.CanPush() { err := errors.New("row buffer cannot be pushed") panic(err) } this.input_q.Push(memory_command) } func (this *RowBuffer) CanPop() bool { return this.ready_q.CanPop(1) } func (this *RowBuffer) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("row buffer cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *RowBuffer) Flush() { if this.row_address != nil { this.WriteToMram() this.row_address = nil this.row_buffer = nil } } func (this *RowBuffer) Cycle() { this.ServiceInputQ() this.ServiceActivationQ() this.ServiceIoQ() this.ServiceBusQ() this.ServicePrechargeQ() this.input_q.Cycle() this.ready_q.Cycle() this.activation_q.Cycle() this.io_q.Cycle() this.bus_q.Cycle() this.precharge_q.Cycle() } func (this *RowBuffer) ServiceInputQ() { if this.input_q.CanPop(1) { memory_command, _ := this.input_q.Front(0) memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { if this.activation_q.IsEmpty() && this.row_address == nil { this.activation_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == READ { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == WRITE { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == PRECHARGE { if this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() { this.precharge_q.Push(memory_command) this.input_q.Pop() } } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServiceActivationQ() { if !this.activation_q.IsEmpty() { memory_command, cycle := this.activation_q.Front(0) if cycle == this.t_ras-this.t_rcd { if this.row_address != nil { err := errors.New("row buffer is not precharged") panic(err) } else if memory_command.Address()%this.wordline_size != 0 { err := errors.New("memory command is not aligned with wordline size") panic(err) } this.row_address = new(int64) *this.row_address = memory_command.Address() this.row_buffer = this.ReadFromMram() } } if this.activation_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.activation_q.Pop() this.ready_q.Push(memory_command) this.stat_factory.Increment("num_activations", 1) } } func (this *RowBuffer) ServiceIoQ() { if this.io_q.CanPop(1) && this.bus_q.CanPush(1) { memory_command := this.io_q.Pop() this.bus_q.Push(memory_command) } } func (this *RowBuffer) ServiceBusQ() { if this.bus_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.bus_q.Pop() this.ready_q.Push(memory_command) memory_operation := memory_command.MemoryOperation() if memory_operation == READ { byte_stream := this.ReadFromRowBuffer(memory_command.Address(), memory_command.Size()) memory_command.SetByteStream(byte_stream) this.stat_factory.Increment("num_reads", 1) this.stat_factory.Increment("read_bytes", memory_command.Size()) } else if memory_operation == WRITE { this.WriteToRowBuffer(memory_command.Address(), memory_command.Size(), memory_command.ByteStream()) this.stat_factory.Increment("num_writes", 1) this.stat_factory.Increment("write_bytes", memory_command.Size()) } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServicePrechargeQ() { if this.precharge_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.precharge_q.Pop() address := memory_command.Address() if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if address != *this.row_address { err := errors.New("address != row address") panic(err) } this.WriteToMram() this.row_address = nil this.ready_q.Push(memory_command) this.stat_factory.Increment("num_precharges", 1) } } func (this *RowBuffer) ReadFromMram() *encoding.ByteStream { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } return this.mram.Read(*this.row_address) } func (this *RowBuffer) ReadFromRowBuffer(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.row_buffer.Get(index)) } return byte_stream } func (this *RowBuffer) WriteToMram() { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } this.mram.Write(*this.row_address, this.row_buffer.Size(), this.row_buffer) } func (this *RowBuffer) WriteToRowBuffer( address int64, size int64, byte_stream *encoding.ByteStream, ) { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(address) + int(i) this.row_buffer.Set(index, byte_stream.Get(int(i))) } } func (this *RowBuffer) Index(address int64) int { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if address < *this.row_address { err := errors.New("address < row address") panic(err) } else if address >= *this.row_address+this.wordline_size { err := errors.New("address >= row address + wordline size") panic(err) } return int(address - *this.row_address) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/dram/wordline.go ================================================ package dram import ( "errors" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Wordline struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Wordline) Init(address int64, size int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_size := int64(config_loader.MramDataWidth() / 8) if address < 0 { err := errors.New("address < 0") panic(err) } else if size <= 0 { err := errors.New("size <= 0") panic(err) } else if size%mram_data_size != 0 { err := errors.New("size is not aligned with MRAM data size") panic(err) } this.address = address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } } func (this *Wordline) Fini() { } func (this *Wordline) Read() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < this.byte_stream.Size(); i++ { byte_stream.Append(this.byte_stream.Get(int(i))) } return byte_stream } func (this *Wordline) Write(byte_stream *encoding.ByteStream) { if this.size != byte_stream.Size() { err := errors.New("wordline's size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/alu.go ================================================ package logic import ( "errors" "uPIMulator/src/device/abi" "uPIMulator/src/misc" ) type Alu struct { } func (this *Alu) Init() { } func (this *Alu) Fini() { } func (this *Alu) AtomicAddressHash(operand1 int64, operand2 int64) int64 { if operand1+operand2 >= 256 { err := errors.New("operand1 + operand2 >= 256") panic(err) } result, _, _ := this.Add(operand1, operand2) return result } func (this *Alu) Add(operand1 int64, operand2 int64) (int64, bool, bool) { return this.Addc(operand1, operand2, false) } func (this *Alu) Addc(operand1 int64, operand2 int64, carry_flag bool) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 if carry_flag { result = word1.Value(abi.UNSIGNED) + word2.Value(abi.UNSIGNED) + 1 } else { result = word1.Value(abi.UNSIGNED) + word2.Value(abi.UNSIGNED) } max_unsigned_value := this.Pow2(mram_data_width) - 1 var carry bool if result > max_unsigned_value { result %= this.Pow2(mram_data_width) carry = true } else { carry = false } result_word := new(abi.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else if !word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else { overflow = false } return result_word.Value(abi.SIGNED), carry, overflow } func (this *Alu) Sub(operand1 int64, operand2 int64) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 var carry bool if word1.Value(abi.UNSIGNED) >= word2.Value(abi.UNSIGNED) { result = word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) carry = true } result_word := new(abi.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else if !word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else { overflow = false } return result, carry, overflow } func (this *Alu) Subc(operand1 int64, operand2 int64, carry_flag bool) (int64, bool, bool) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) var result int64 var carry bool if carry_flag { if word1.Value(abi.UNSIGNED)+1 >= word2.Value(abi.UNSIGNED) { result = word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) - 1 carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) - 1 carry = true } } else { if word1.Value(abi.UNSIGNED) >= word2.Value(abi.UNSIGNED) { result = word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) carry = false } else { result = this.Pow2(mram_data_width) + word1.Value(abi.UNSIGNED) - word2.Value(abi.UNSIGNED) carry = true } } result_word := new(abi.Word) result_word.Init(mram_data_width) result_word.SetValue(result) var overflow bool if word1.SignBit() && !word2.SignBit() && result_word.SignBit() { overflow = true } else if !word1.SignBit() && word2.SignBit() && !result_word.SignBit() { overflow = true } else { overflow = false } return result, carry, overflow } func (this *Alu) And(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Nand(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Andn(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Or(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) || word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Nor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if word1.Bit(i) || word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Orn(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) || word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Xor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.SetBit(i) } else if word1.Bit(i) && !word2.Bit(i) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Nxor(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if !word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else if word1.Bit(i) && word2.Bit(i) { result_word.ClearBit(i) } else { result_word.SetBit(i) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Asr(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) msb := word_.SignBit() shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { if msb { result_word.SetBit(i) } else { result_word.ClearBit(i) } } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Lsl(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { result_word.ClearBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) LslAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Lsl(operand2, shift)) } func (this *Alu) LslSub(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Sub(operand1, this.Lsl(operand2, shift)) } func (this *Alu) Lsl1(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { result_word.SetBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Lsl1x(operand int64, shift int64) int64 { err := errors.New("lsl1x is not yet implemented") panic(err) } func (this *Alu) Lslx(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) if shift_value == 0 { return 0 } else { return this.Lsr(operand, int64(mram_data_width)-shift_value) } } func (this *Alu) Lsr(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { result_word.ClearBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) LsrAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Lsr(operand2, shift)) } func (this *Alu) Lsr1(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { result_word.SetBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Lsr1x(operand int64, shift int64) int64 { err := errors.New("lsr1x is not yet implemented") panic(err) } func (this *Alu) Lsrx(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) if shift_value == 0 { return 0 } else { return this.Lsl(operand, int64(mram_data_width)-shift_value) } } func (this *Alu) Rol(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i < int(shift_value) { if word_.Bit(i + mram_data_width - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } result_word.SetBit(i) } else { if word_.Bit(i - int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) RolAdd(operand1 int64, operand2 int64, shift int64) (int64, bool, bool) { return this.Add(operand1, this.Rol(operand2, shift)) } func (this *Alu) Ror(operand int64, shift int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) shift_word := new(abi.Word) shift_word.Init(mram_data_width) shift_word.SetValue(shift) shift_value := shift_word.BitSlice(abi.UNSIGNED, 0, 5) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < mram_data_width; i++ { if i+int(shift_value) >= mram_data_width { if word_.Bit((i + int(shift_value)) % mram_data_width) { result_word.SetBit(i) } else { result_word.ClearBit(i) } result_word.SetBit(i) } else { if word_.Bit(i + int(shift_value)) { result_word.SetBit(i) } else { result_word.ClearBit(i) } } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Cao(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) ones := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(i) { ones++ } } return ones } func (this *Alu) Clo(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) leading_ones := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(mram_data_width - 1 - i) { leading_ones++ } else { break } } return leading_ones } func (this *Alu) Cls(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) msb := word_.SignBit() leading_sign_bits := int64(0) for i := 0; i < mram_data_width; i++ { if word_.Bit(mram_data_width-1-i) == msb { leading_sign_bits++ } else { break } } return leading_sign_bits } func (this *Alu) Clz(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) leading_zeros := int64(0) for i := 0; i < mram_data_width; i++ { if !word_.Bit(mram_data_width - 1 - i) { leading_zeros++ } else { break } } return leading_zeros } func (this *Alu) Cmpb4(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) for i := 0; i < 4; i++ { begin := 8 * i end := 8 * (i + 1) byte1 := word1.BitSlice(abi.UNSIGNED, begin, end) byte2 := word2.BitSlice(abi.UNSIGNED, begin, end) if byte1 == byte2 { result_word.SetBitSlice(begin, end, 1) } else { result_word.SetBitSlice(begin, end, 0) } } return result_word.Value(abi.UNSIGNED) } func (this *Alu) Extsb(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(abi.SIGNED, 0, 8) } func (this *Alu) Extsh(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(abi.SIGNED, 0, 16) } func (this *Alu) Extub(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(abi.UNSIGNED, 0, 8) } func (this *Alu) Extuh(operand int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) return word_.BitSlice(abi.UNSIGNED, 0, 16) } func (this *Alu) MulShSh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 8, 16) * word2.BitSlice(abi.SIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulShSl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 8, 16) * word2.BitSlice(abi.SIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulShUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 8, 16) * word2.BitSlice(abi.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulShUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 8, 16) * word2.BitSlice(abi.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulSlSh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 0, 8) * word2.BitSlice(abi.SIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulSlSl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 0, 8) * word2.BitSlice(abi.SIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulSlUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 0, 8) * word2.BitSlice(abi.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulSlUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.SIGNED, 0, 8) * word2.BitSlice(abi.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.SIGNED) } func (this *Alu) MulUhUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.UNSIGNED, 8, 16) * word2.BitSlice(abi.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.UNSIGNED) } func (this *Alu) MulUhUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.UNSIGNED, 8, 16) * word2.BitSlice(abi.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.UNSIGNED) } func (this *Alu) MulUlUh(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.UNSIGNED, 0, 8) * word2.BitSlice(abi.UNSIGNED, 8, 16) result_word.SetValue(result) return result_word.Value(abi.UNSIGNED) } func (this *Alu) MulUlUl(operand1 int64, operand2 int64) int64 { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() if mram_data_width != 4*8 { err := errors.New("MRAM data width != 4 * 8") panic(err) } word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) result_word := new(abi.Word) result_word.Init(mram_data_width) result := word1.BitSlice(abi.UNSIGNED, 0, 8) * word2.BitSlice(abi.UNSIGNED, 0, 8) result_word.SetValue(result) return result_word.Value(abi.UNSIGNED) } func (this *Alu) Sats(operand int64) int64 { err := errors.New("sats is not yet implemented") panic(err) } func (this *Alu) Hash(operand1 int64, operand2 int64) int64 { err := errors.New("hash is not yet implemented") panic(err) } func (this *Alu) SignedExtension(operand int64) (int64, int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) even_word := new(abi.Word) even_word.Init(mram_data_width) if word_.SignBit() { even_word.SetValue(-1) } odd_word := new(abi.Word) odd_word.Init(mram_data_width) odd_word.SetValue(word_.Value(abi.UNSIGNED)) return even_word.Value(abi.UNSIGNED), odd_word.Value(abi.UNSIGNED) } func (this *Alu) UnsignedExtension(operand int64) (int64, int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word_ := new(abi.Word) word_.Init(mram_data_width) word_.SetValue(operand) even_word := new(abi.Word) even_word.Init(mram_data_width) even_word.SetValue(0) odd_word := new(abi.Word) odd_word.Init(mram_data_width) odd_word.SetValue(word_.Value(abi.UNSIGNED)) return even_word.Value(abi.UNSIGNED), odd_word.Value(abi.UNSIGNED) } func (this *Alu) Pow2(exponent int) int64 { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/cycle_rule.go ================================================ package logic import ( "errors" "fmt" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/misc" ) type CycleRule struct { channel_id int rank_id int dpu_id int input_q *InstructionQ wait_q *InstructionQ ready_q *InstructionQ scoreboard map[*instruction.Instruction]*Thread reg_sets []*RegSet stat_factory *misc.StatFactory } func (this *CycleRule) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id num_tasklets := int(command_line_parser.IntParameter("num_tasklets")) this.input_q = new(InstructionQ) this.input_q.Init(1, 0) this.wait_q = new(InstructionQ) this.wait_q.Init(1, 0) this.ready_q = new(InstructionQ) this.ready_q.Init(1, 0) this.scoreboard = make(map[*instruction.Instruction]*Thread) for i := 0; i < num_tasklets; i++ { reg_set := new(RegSet) reg_set.Init(i) this.reg_sets = append(this.reg_sets, reg_set) } name := fmt.Sprintf("CycleRule[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *CycleRule) Fini() { this.input_q.Fini() this.wait_q.Fini() this.ready_q.Fini() } func (this *CycleRule) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *CycleRule) IsEmpty() bool { return this.input_q.IsEmpty() && this.wait_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *CycleRule) CanPush() bool { return this.input_q.CanPush(1) } func (this *CycleRule) Push(instruction_ *instruction.Instruction, thread *Thread) { if !this.CanPush() { err := errors.New("cycle rule cannot be pushed") panic(err) } this.input_q.Push(instruction_) this.scoreboard[instruction_] = thread } func (this *CycleRule) CanPop() bool { return this.ready_q.CanPop(1) } func (this *CycleRule) Pop() *instruction.Instruction { if !this.CanPop() { err := errors.New("cycle rule cannot be popped") panic(err) } instruction_ := this.ready_q.Pop() delete(this.scoreboard, instruction_) return instruction_ } func (this *CycleRule) Cycle() { this.ServiceInputQ() this.ServiceWaitQ() this.input_q.Cycle() this.wait_q.Cycle() this.ready_q.Cycle() } func (this *CycleRule) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) { instruction_ := this.input_q.Pop() thread_id := this.scoreboard[instruction_].ThreadId() this.reg_sets[thread_id].CollectReadGpRegs(instruction_) extra_cycles := this.CalculateExtraCycles(instruction_) this.wait_q.PushWithTimer(instruction_, extra_cycles) this.stat_factory.Increment("cycle_rule", extra_cycles) } } func (this *CycleRule) ServiceWaitQ() { if this.wait_q.CanPop(1) && this.ready_q.CanPush(1) { instruction_ := this.wait_q.Pop() this.ready_q.Push(instruction_) thread_id := this.scoreboard[instruction_].ThreadId() this.reg_sets[thread_id].Clear() this.reg_sets[thread_id].CollectWriteGpRegs(instruction_) } } func (this *CycleRule) CalculateExtraCycles(instruction_ *instruction.Instruction) int64 { thread_id := this.scoreboard[instruction_].ThreadId() reg_set := this.reg_sets[thread_id] if reg_set.ThreadId() != thread_id { err := errors.New("reg set's thread ID != thread ID") panic(err) } reg_indicies := reg_set.RegIndices() even_counter := 0 odd_counter := 0 for reg_index, _ := range reg_indicies { if reg_index%2 == 0 { even_counter++ } else { odd_counter++ } } return int64(even_counter/2 + odd_counter/2) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/dma.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/device/simulator/dpu/sram" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Dma struct { atomic *sram.Atomic iram *sram.Iram operand_collector *OperandCollector memory_controller *dram.MemoryController input_q *dram.DmaCommandQ ready_q *dram.DmaCommandQ } func (this *Dma) Init() { this.atomic = nil this.iram = nil this.operand_collector = nil this.memory_controller = nil config_loader := new(misc.ConfigLoader) config_loader.Init() max_num_tasklets := config_loader.MaxNumTasklets() this.input_q = new(dram.DmaCommandQ) this.input_q.Init(max_num_tasklets, 0) this.ready_q = new(dram.DmaCommandQ) this.ready_q.Init(max_num_tasklets, 0) } func (this *Dma) Fini() { this.input_q.Fini() this.ready_q.Fini() } func (this *Dma) ConnectAtomic(atomic *sram.Atomic) { if this.atomic != nil { err := errors.New("atomic is already set") panic(err) } this.atomic = atomic } func (this *Dma) ConnectIram(iram *sram.Iram) { if this.iram != nil { err := errors.New("IRAM is already set") panic(err) } this.iram = iram } func (this *Dma) ConnectOperandCollector(operand_collector *OperandCollector) { if this.operand_collector != nil { err := errors.New("operand collector is already set") panic(err) } this.operand_collector = operand_collector } func (this *Dma) ConnectMemoryController(memory_controller *dram.MemoryController) { if this.memory_controller != nil { err := errors.New("memory controller is already set") panic(err) } this.memory_controller = memory_controller } func (this *Dma) IsEmpty() bool { return this.input_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *Dma) TransferToAtomic(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { if byte_stream.Get(int(i)) != 0 { err := errors.New("atomic byte is not set to 0") panic(err) } } } func (this *Dma) TransferToIram(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } config_loader := new(misc.ConfigLoader) config_loader.Init() iram_offset := config_loader.IramOffset() iram_data_size := int64(config_loader.IramDataWidth() / 8) if address != this.iram.Address() { err := errors.New("address != IRAM's address") panic(err) } else if byte_stream.Size()%iram_data_size != 0 { err := errors.New("byte stream's size is not aligned with IRAM data size") panic(err) } this.iram.Write(iram_offset, size, byte_stream) } func (this *Dma) TransferFromWram(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { value := this.operand_collector.Lbu(address + i) byte_stream.Append(uint8(value)) } return byte_stream } func (this *Dma) TransferToWram(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) this.operand_collector.Sb(address+i, int64(value)) } } func (this *Dma) TransferFromMram(address int64, size int64) *encoding.ByteStream { this.memory_controller.Flush() return this.memory_controller.Read(address, size) } func (this *Dma) TransferToMram(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } this.memory_controller.Write(address, size, byte_stream) } func (this *Dma) TransferFromWramToMram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } byte_stream := this.TransferFromWram(wram_address, size) dma_command := new(dram.DmaCommand) dma_command.InitWriteToMramFromWram(wram_address, mram_address, size, byte_stream, instruction_) this.Push(dma_command) } func (this *Dma) TransferFromMramToWram( wram_address int64, mram_address int64, size int64, instruction_ *instruction.Instruction, ) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } dma_command := new(dram.DmaCommand) dma_command.InitReadFromMramToWram(wram_address, mram_address, size, instruction_) this.Push(dma_command) } func (this *Dma) CanPush() bool { return this.input_q.CanPush(1) } func (this *Dma) Push(dma_command *dram.DmaCommand) { if !this.CanPush() { err := errors.New("DMA cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *Dma) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Dma) Pop() *dram.DmaCommand { if !this.CanPop() { err := errors.New("DMA cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Dma) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() this.input_q.Cycle() this.ready_q.Cycle() } func (this *Dma) ServiceInputQ() { if this.input_q.CanPop(1) && this.memory_controller.CanPush() { dma_command := this.input_q.Pop() this.memory_controller.Push(dma_command) } } func (this *Dma) ServiceReadyQ() { if this.memory_controller.CanPop() && this.ready_q.CanPush(1) { dma_command := this.memory_controller.Pop() this.ready_q.Push(dma_command) if dma_command.HasInstruction() && dma_command.MemoryOperation() == dram.READ { wram_address := dma_command.WramAddress() mram_address := dma_command.MramAddress() size := dma_command.Size() byte_stream := dma_command.ByteStream(mram_address, size) this.TransferToWram(wram_address, byte_stream.Size(), byte_stream) } } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/instruction_q.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" ) type InstructionQ struct { size int timer int64 instructions []*instruction.Instruction cycles []int64 } func (this *InstructionQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.instructions = make([]*instruction.Instruction, 0) this.cycles = make([]int64, 0) } func (this *InstructionQ) Fini() { if !this.IsEmpty() { err := errors.New("instruction queue is not empty") panic(err) } } func (this *InstructionQ) Size() int { return this.size } func (this *InstructionQ) Length() int { return len(this.instructions) } func (this *InstructionQ) Timer() int64 { return this.timer } func (this *InstructionQ) IsEmpty() bool { return len(this.instructions) == 0 } func (this *InstructionQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.instructions) >= num_items } else { return true } } func (this *InstructionQ) Push(instruction_ *instruction.Instruction) { if !this.CanPush(1) { err := errors.New("instruction queue cannot be pushed") panic(err) } this.instructions = append(this.instructions, instruction_) this.cycles = append(this.cycles, this.timer) } func (this *InstructionQ) PushWithTimer(instruction_ *instruction.Instruction, timer int64) { if !this.CanPush(1) { err := errors.New("instruction queue cannot be pushed") panic(err) } this.instructions = append(this.instructions, instruction_) this.cycles = append(this.cycles, timer) } func (this *InstructionQ) CanPop(num_items int) bool { if len(this.instructions) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *InstructionQ) Pop() *instruction.Instruction { if !this.CanPop(1) { err := errors.New("instruction queue cannot be popped") panic(err) } instruction_ := this.instructions[0] this.instructions = this.instructions[1:] this.cycles = this.cycles[1:] return instruction_ } func (this *InstructionQ) Front(pos int) (*instruction.Instruction, int64) { return this.instructions[pos], this.cycles[pos] } func (this *InstructionQ) Remove(pos int) { this.instructions = append(this.instructions[:pos], this.instructions[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *InstructionQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/logic.go ================================================ package logic import ( "errors" "fmt" "math" "uPIMulator/src/device/abi" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/device/linker/kernel/instruction/cc" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/device/simulator/dpu/sram" "uPIMulator/src/misc" ) type Logic struct { channel_id int rank_id int dpu_id int num_channels int num_ranks_per_channel int num_dpus_per_rank int verbose int min_access_granularity int64 thread_scheduler *ThreadScheduler atomic *sram.Atomic iram *sram.Iram operand_collector *OperandCollector dma *Dma scoreboard map[*instruction.Instruction]*Thread pipeline *Pipeline cycle_rule *CycleRule alu *Alu wait_q *InstructionQ stat_factory *misc.StatFactory } func (this *Logic) Init( channel_id int, rank_id int, dpu_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.num_channels = int(command_line_parser.IntParameter("num_channels")) this.num_ranks_per_channel = int(command_line_parser.IntParameter("num_ranks_per_channel")) this.num_dpus_per_rank = int(command_line_parser.IntParameter("num_dpus_per_rank")) this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.verbose = int(command_line_parser.IntParameter("verbose")) this.thread_scheduler = nil this.atomic = nil this.iram = nil this.operand_collector = nil this.dma = nil this.scoreboard = make(map[*instruction.Instruction]*Thread) this.pipeline = new(Pipeline) this.pipeline.Init(command_line_parser) this.cycle_rule = new(CycleRule) this.cycle_rule.Init(channel_id, rank_id, dpu_id, command_line_parser) this.alu = new(Alu) this.alu.Init() config_loader := new(misc.ConfigLoader) config_loader.Init() this.wait_q = new(InstructionQ) this.wait_q.Init(config_loader.MaxNumTasklets(), 0) name := fmt.Sprintf("Logic[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *Logic) Fini() { this.pipeline.Fini() this.cycle_rule.Fini() this.alu.Fini() this.wait_q.Fini() } func (this *Logic) ConnectThreadScheduler(thread_scheduler *ThreadScheduler) { if this.thread_scheduler != nil { err := errors.New("thread scheduler is already set") panic(err) } this.thread_scheduler = thread_scheduler } func (this *Logic) ConnectAtomic(atomic *sram.Atomic) { if this.atomic != nil { err := errors.New("atomic is already set") panic(err) } this.atomic = atomic } func (this *Logic) ConnectIram(iram *sram.Iram) { if this.iram != nil { err := errors.New("IRAM is already set") panic(err) } this.iram = iram } func (this *Logic) ConnectOperandCollector(operand_collector *OperandCollector) { if this.operand_collector != nil { err := errors.New("operand collector is already set") panic(err) } this.operand_collector = operand_collector } func (this *Logic) ConnectDma(dma *Dma) { if this.dma != nil { err := errors.New("DMA is already set") panic(err) } this.dma = dma } func (this *Logic) CycleRule() *CycleRule { return this.cycle_rule } func (this *Logic) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *Logic) IsEmpty() bool { return this.pipeline.IsEmpty() && this.cycle_rule.IsEmpty() && this.wait_q.IsEmpty() } func (this *Logic) Cycle() { this.ServiceThreadScheduler() this.ServicePipeline() this.ServiceCycleRule() this.ServiceLogic() this.ServiceDma() this.pipeline.Cycle() this.cycle_rule.Cycle() this.stat_factory.Increment("logic_cycle", 1) } func (this *Logic) ServiceThreadScheduler() { if this.pipeline.CanPush() && this.cycle_rule.CanPush() && this.wait_q.CanPush(1) { thread := this.thread_scheduler.Schedule() if thread != nil { pc := thread.RegFile().ReadPcReg() instruction_ := this.iram.Read(pc) this.scoreboard[instruction_] = thread this.pipeline.Push(instruction_) if instruction_.Suffix() != instruction.DMA_RRI { this.ExecuteInstruction(instruction_) } else { this.thread_scheduler.Block(thread.ThreadId()) thread.RegFile().IncrementPcReg() this.wait_q.Push(instruction_) } this.stat_factory.Increment("num_instructions", 1) } active_tasklets := fmt.Sprintf( "active_tasklets_%d", this.thread_scheduler.NumIssuableThreads(), ) this.stat_factory.Increment(active_tasklets, 1) } else { this.stat_factory.Increment("backpressure", 1) this.stat_factory.Increment("active_tasklets_0", 1) } } func (this *Logic) ServicePipeline() { if this.pipeline.CanPop() && this.cycle_rule.CanPush() { instruction_ := this.pipeline.Pop() thread := this.scoreboard[instruction_] if instruction_ != nil { this.cycle_rule.Push(instruction_, thread) } } } func (this *Logic) ServiceCycleRule() { if this.cycle_rule.CanPop() { instruction_ := this.cycle_rule.Pop() if instruction_.Suffix() != instruction.DMA_RRI { delete(this.scoreboard, instruction_) } else { this.ExecuteInstruction(instruction_) } } } func (this *Logic) ServiceLogic() { } func (this *Logic) ServiceDma() { if this.dma.CanPop() { dma_command := this.dma.Pop() has_waked_up := false for i := 0; this.wait_q.CanPop(i + 1); i++ { instruction_, _ := this.wait_q.Front(i) if dma_command.Instruction() == instruction_ { thread := this.scoreboard[instruction_] this.thread_scheduler.Awake(thread.ThreadId()) this.wait_q.Remove(i) delete(this.scoreboard, instruction_) has_waked_up = true break } } if !has_waked_up { err := errors.New("DMA command has not waked up an instruction") panic(err) } } } func (this *Logic) ExecuteInstruction(instruction_ *instruction.Instruction) { thread := this.scoreboard[instruction_] unique_dpu_id := this.channel_id*this.num_ranks_per_channel*this.num_dpus_per_rank + this.rank_id*this.num_dpus_per_rank + this.dpu_id if this.verbose >= 1 { fmt.Printf( "{%d}[%d] %s\n", unique_dpu_id, thread.ThreadId(), instruction_.Stringify(), ) } suffix := instruction_.Suffix() if suffix == instruction.RICI { this.ExecuteRici(instruction_) } else if suffix == instruction.RRI { this.ExecuteRri(instruction_) } else if suffix == instruction.RRIC { this.ExecuteRric(instruction_) } else if suffix == instruction.RRICI { this.ExecuteRrici(instruction_) } else if suffix == instruction.RRIF { this.ExecuteRrif(instruction_) } else if suffix == instruction.RRR { this.ExecuteRrr(instruction_) } else if suffix == instruction.RRRC { this.ExecuteRrrc(instruction_) } else if suffix == instruction.RRRCI { this.ExecuteRrrci(instruction_) } else if suffix == instruction.ZRI { this.ExecuteZri(instruction_) } else if suffix == instruction.ZRIC { this.ExecuteZric(instruction_) } else if suffix == instruction.ZRICI { this.ExecuteZrici(instruction_) } else if suffix == instruction.ZRIF { this.ExecuteZrif(instruction_) } else if suffix == instruction.ZRR { this.ExecuteZrr(instruction_) } else if suffix == instruction.ZRRC { this.ExecuteZrrc(instruction_) } else if suffix == instruction.ZRRCI { this.ExecuteZrrci(instruction_) } else if suffix == instruction.S_RRI || suffix == instruction.U_RRI { this.ExecuteSRri(instruction_) } else if suffix == instruction.S_RRIC || suffix == instruction.U_RRIC { this.ExecuteSRric(instruction_) } else if suffix == instruction.S_RRICI || suffix == instruction.U_RRICI { this.ExecuteSRrici(instruction_) } else if suffix == instruction.S_RRIF || suffix == instruction.U_RRIF { this.ExecuteSRrif(instruction_) } else if suffix == instruction.S_RRR || suffix == instruction.U_RRR { this.ExecuteSRrr(instruction_) } else if suffix == instruction.S_RRRC || suffix == instruction.U_RRRC { this.ExecuteSRrrc(instruction_) } else if suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI { this.ExecuteSRrrci(instruction_) } else if suffix == instruction.RR { this.ExecuteRr(instruction_) } else if suffix == instruction.RRC { this.ExecuteRrc(instruction_) } else if suffix == instruction.RRCI { this.ExecuteRrci(instruction_) } else if suffix == instruction.ZR { this.ExecuteZr(instruction_) } else if suffix == instruction.ZRC { this.ExecuteZrc(instruction_) } else if suffix == instruction.ZRCI { this.ExecuteZrci(instruction_) } else if suffix == instruction.S_RR || suffix == instruction.U_RR { this.ExecuteSRr(instruction_) } else if suffix == instruction.S_RRC || suffix == instruction.U_RRC { this.ExecuteSRrc(instruction_) } else if suffix == instruction.S_RRCI || suffix == instruction.U_RRCI { this.ExecuteSRrci(instruction_) } else if suffix == instruction.DRDICI { this.ExecuteDrdici(instruction_) } else if suffix == instruction.RRRI { this.ExecuteRrri(instruction_) } else if suffix == instruction.RRRICI { this.ExecuteRrrici(instruction_) } else if suffix == instruction.ZRRI { this.ExecuteZrri(instruction_) } else if suffix == instruction.ZRRICI { this.ExecuteZrrici(instruction_) } else if suffix == instruction.S_RRRI || suffix == instruction.U_RRRI { this.ExecuteSRrri(instruction_) } else if suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI { this.ExecuteSRrrici(instruction_) } else if suffix == instruction.RIR { this.ExecuteRir(instruction_) } else if suffix == instruction.RIRC { this.ExecuteRirc(instruction_) } else if suffix == instruction.RIRCI { this.ExecuteRirci(instruction_) } else if suffix == instruction.ZIR { this.ExecuteZir(instruction_) } else if suffix == instruction.ZIRC { this.ExecuteZirc(instruction_) } else if suffix == instruction.ZIRCI { this.ExecuteZirci(instruction_) } else if suffix == instruction.S_RIRC || suffix == instruction.U_RIRC { this.ExecuteSRirc(instruction_) } else if suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI { this.ExecuteSRirci(instruction_) } else if suffix == instruction.R { this.ExecuteR(instruction_) } else if suffix == instruction.RCI { this.ExecuteRci(instruction_) } else if suffix == instruction.Z { this.ExecuteZ(instruction_) } else if suffix == instruction.ZCI { this.ExecuteZci(instruction_) } else if suffix == instruction.S_R || suffix == instruction.U_R { this.ExecuteSR(instruction_) } else if suffix == instruction.S_RCI || suffix == instruction.U_RCI { this.ExecuteSRci(instruction_) } else if suffix == instruction.CI { this.ExecuteCi(instruction_) } else if suffix == instruction.I { this.ExecuteI(instruction_) } else if suffix == instruction.DDCI { this.ExecuteDdci(instruction_) } else if suffix == instruction.ERRI { this.ExecuteErri(instruction_) } else if suffix == instruction.S_ERRI || suffix == instruction.U_ERRI { this.ExecuteSErri(instruction_) } else if suffix == instruction.EDRI { this.ExecuteEdri(instruction_) } else if suffix == instruction.ERII { this.ExecuteErii(instruction_) } else if suffix == instruction.ERIR { this.ExecuteErir(instruction_) } else if suffix == instruction.ERID { this.ExecuteErid(instruction_) } else if suffix == instruction.DMA_RRI { this.ExecuteDmaRri(instruction_) } else { err := errors.New("suffix is not valid") panic(err) } if this.verbose >= 2 { fmt.Println(this.PrintRegFile(thread)) } } func (this *Logic) ExecuteRici(instruction_ *instruction.Instruction) { if _, found := instruction_.RiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } op_code := instruction_.OpCode() if _, is_acquire_rici_op_code := instruction_.AcquireRiciOpCodes()[op_code]; is_acquire_rici_op_code { this.ExecuteAcquireRici(instruction_) } else if _, is_release_rici_op_code := instruction_.ReleaseRiciOpCodes()[op_code]; is_release_rici_op_code { this.ExecuteReleaseRici(instruction_) } else if _, is_boot_rici_op_code := instruction_.BootRiciOpCodes()[op_code]; is_boot_rici_op_code { this.ExecuteBootRici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAcquireRici(instruction_ *instruction.Instruction) { if _, found := instruction_.AcquireRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid acquire RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.UNSIGNED) imm := instruction_.Imm().Value() atomic_address := this.alu.AtomicAddressHash(ra, imm) can_acquire := this.atomic.CanAcquire(atomic_address) if can_acquire { this.atomic.Acquire(atomic_address, thread.ThreadId()) } thread.RegFile().ClearConditions() if can_acquire { this.SetAcquireCc(instruction_, 0) } else { this.SetAcquireCc(instruction_, 1) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } if can_acquire { this.SetFlags(instruction_, 0, false) } else { this.SetFlags(instruction_, 1, false) } } func (this *Logic) ExecuteReleaseRici(instruction_ *instruction.Instruction) { if _, found := instruction_.ReleaseRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid release RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.UNSIGNED) imm := instruction_.Imm().Value() atomic_address := this.alu.AtomicAddressHash(ra, imm) can_release := this.atomic.CanRelease(atomic_address, thread.ThreadId()) if can_release { this.atomic.Release(atomic_address, thread.ThreadId()) } thread.RegFile().ClearConditions() if can_release { this.SetAcquireCc(instruction_, 0) } else { this.SetAcquireCc(instruction_, 1) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } if can_release { this.SetFlags(instruction_, 0, false) } else { this.SetFlags(instruction_, 1, false) } } func (this *Logic) ExecuteBootRici(instruction_ *instruction.Instruction) { if _, found := instruction_.BootRiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid boot RICI op code") panic(err) } else if instruction_.Suffix() != instruction.RICI { err := errors.New("suffix is not RICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.UNSIGNED) imm := instruction_.Imm().Value() thread_id := int(this.alu.AtomicAddressHash(ra, imm)) thread.RegFile().ClearConditions() op_code := instruction_.OpCode() if op_code == instruction.BOOT { can_boot := this.thread_scheduler.Boot(thread_id) if can_boot { this.SetBootCc(instruction_, ra, 0) this.SetFlags(instruction_, 0, false) } else { this.SetBootCc(instruction_, ra, 1) this.SetFlags(instruction_, 1, false) } } else if op_code == instruction.RESUME { can_resume := this.thread_scheduler.Awake(thread_id) if can_resume { this.SetBootCc(instruction_, ra, 0) this.SetFlags(instruction_, 0, false) } else { this.SetBootCc(instruction_, ra, 1) this.SetFlags(instruction_, 1, false) } } else { err := errors.New("op code is not valid") panic(err) } if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteRri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddRri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrRri(instruction_) } else if _, is_call_rri_op_code := instruction_.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.ExecuteCallRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteCallRri(instruction_ *instruction.Instruction) { if _, found := instruction_.CallRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid call RRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRI { err := errors.New("suffix is not RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if imm == 0 { result, carry, _ = this.alu.Add(ra, imm) } else { result, carry, _ = this.alu.Add(ra*iram_data_size, imm) } thread.RegFile().ClearConditions() pc := thread.RegFile().ReadPcReg() thread.RegFile().WriteGpReg(instruction_.Rc(), pc+iram_data_size) thread.RegFile().WritePcReg(result) this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRric(instruction_ *instruction.Instruction) { if _, found := instruction_.RricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rric_op_code := instruction_.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.ExecuteAddRric(instruction_) } else if _, is_asrc_rric_op_code := instruction_.AsrRricOpCodes()[op_code]; is_asrc_rric_op_code { this.ExecuteAsrRric(instruction_) } else if _, is_sub_rric_op_code := instruction_.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.ExecuteSubRric(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRric(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrRric(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubRric(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.RRIC { err := errors.New("suffix is not RRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, imm, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddRrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndRrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrRrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubRrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.RRICI { err := errors.New("suffix is not RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.RRIF { err := errors.New("suffix is not RRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } else if instruction_.Suffix() != instruction.RRR { err := errors.New("suffix is not RRR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, rb, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() if op_code != instruction.CALL { thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() } else { config_loader := new(misc.ConfigLoader) config_loader.Init() pc := thread.RegFile().ReadPcReg() iram_data_size := int64(config_loader.IramDataWidth() / 8) thread.RegFile().WriteGpReg(instruction_.Rc(), pc+iram_data_size) thread.RegFile().WritePcReg(result) } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrc_op_code := instruction_.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { this.ExecuteAddRrrc(instruction_) } else if _, is_rsub_rrrc_op_code := instruction_.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { this.ExecuteRsubRrrc(instruction_) } else if _, is_sub_rrrc_op_code := instruction_.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { this.ExecuteSubRrrc(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRsubRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, ra, rb, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSubRrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRRC { err := errors.New("suffix is not RRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, rb, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrci_op_code := instruction_.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { this.ExecuteAddRrrci(instruction_) } else if _, is_and_rrrci_op_code := instruction_.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { this.ExecuteAndRrrci(instruction_) } else if _, is_asr_rrrci_op_code := instruction_.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { this.ExecuteAsrRrrci(instruction_) } else if _, is_mul_rrrci_op_code := instruction_.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { this.ExecuteMulRrrci(instruction_) } else if _, is_rsub_rrrci_op_code := instruction_.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { this.ExecuteRsubRrrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, rb) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.MulRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetMulNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRsubRrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRCI { err := errors.New("suffix is not RRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, overflow = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, rb, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddZri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrZri(instruction_) } else if _, is_call_rri_op_code := instruction_.CallRriOpCodes()[op_code]; is_call_rri_op_code { this.ExecuteCallZri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrZri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteCallZri(instruction_ *instruction.Instruction) { if _, found := instruction_.CallRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid call RRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRI { err := errors.New("suffix is not ZRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if imm == 0 { result, carry, _ = this.alu.Add(ra, imm) } else { result, carry, _ = this.alu.Add(ra*iram_data_size, imm) } thread.RegFile().ClearConditions() thread.RegFile().WritePcReg(result) this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZric(instruction_ *instruction.Instruction) { if _, found := instruction_.RricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rric_op_code := instruction_.AddRricOpCodes()[op_code]; is_add_rric_op_code { this.ExecuteAddZric(instruction_) } else if _, is_asrc_rric_op_code := instruction_.AsrRricOpCodes()[op_code]; is_asrc_rric_op_code { this.ExecuteAsrZric(instruction_) } else if _, is_sub_rric_op_code := instruction_.SubRricOpCodes()[op_code]; is_sub_rric_op_code { this.ExecuteSubZric(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZric(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrZric(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubZric(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRricOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRIC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIC { err := errors.New("suffix is not ZRIC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, imm, result, carry, overflow) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddZrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndZrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrZrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubZrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubZrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRICI { err := errors.New("suffix is not ZRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.ZRIF { err := errors.New("suffix is not ZRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRR op code") panic(err) } else if instruction_.Suffix() != instruction.ZRR { err := errors.New("suffix is not ZRR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, rb, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() if op_code != instruction.CALL { thread.RegFile().IncrementPcReg() } else { thread.RegFile().WritePcReg(result) } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrc_op_code := instruction_.AddRrrcOpCodes()[op_code]; is_add_rrrc_op_code { this.ExecuteAddZrrc(instruction_) } else if _, is_rsub_rrrc_op_code := instruction_.RsubRrrcOpCodes()[op_code]; is_rsub_rrrc_op_code { this.ExecuteRsubZrrc(instruction_) } else if _, is_sub_rrrc_op_code := instruction_.SubRrrcOpCodes()[op_code]; is_sub_rrrc_op_code { this.ExecuteSubZrrc(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, rb) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) carry = false } else if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) carry = false } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) carry = false } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) carry = false } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) carry = false } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) carry = false } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) carry = false } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) carry = false } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) carry = false } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) carry = false } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) carry = false } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) carry = false } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) carry = false } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) carry = false } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) carry = false } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) carry = false } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) carry = false } else if op_code == instruction.CALL { result, carry, _ = this.alu.Add(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRsubZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, _ = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(rb, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, ra, rb, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSubZrrc(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRrrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRC { err := errors.New("suffix is not ZRRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetExtSubSetCc(instruction_, ra, rb, result, carry, overflow) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrrci_op_code := instruction_.AddRrrciOpCodes()[op_code]; is_add_rrrci_op_code { this.ExecuteAddZrrci(instruction_) } else if _, is_and_rrrci_op_code := instruction_.AndRrrciOpCodes()[op_code]; is_and_rrrci_op_code { this.ExecuteAndZrrci(instruction_) } else if _, is_asr_rrrci_op_code := instruction_.AsrRrrciOpCodes()[op_code]; is_asr_rrrci_op_code { this.ExecuteAsrZrrci(instruction_) } else if _, is_mul_rrrci_op_code := instruction_.MulRrrciOpCodes()[op_code]; is_mul_rrrci_op_code { this.ExecuteMulZrrci(instruction_) } else if _, is_rsub_rrrci_op_code := instruction_.RsubRrrciOpCodes()[op_code]; is_rsub_rrrci_op_code { this.ExecuteRsubZrrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, rb) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, rb) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, rb) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, rb) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, rb) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, rb) } else if op_code == instruction.OR { result = this.alu.Or(ra, rb) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, rb) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, rb) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, rb) } else if op_code == instruction.CMPB4 { result = this.alu.Cmpb4(ra, rb) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, rb) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, rb) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, rb) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, rb) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, rb) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, rb) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, rb) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, rb) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, rb) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.MulRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.MUL_SH_SH { result = this.alu.MulShSh(ra, rb) } else if op_code == instruction.MUL_SH_SL { result = this.alu.MulShSl(ra, rb) } else if op_code == instruction.MUL_SH_UH { result = this.alu.MulShUh(ra, rb) } else if op_code == instruction.MUL_SH_UL { result = this.alu.MulShUl(ra, rb) } else if op_code == instruction.MUL_SL_SH { result = this.alu.MulSlSh(ra, rb) } else if op_code == instruction.MUL_SL_SL { result = this.alu.MulSlSl(ra, rb) } else if op_code == instruction.MUL_SL_UH { result = this.alu.MulSlUh(ra, rb) } else if op_code == instruction.MUL_SL_UL { result = this.alu.MulSlUl(ra, rb) } else if op_code == instruction.MUL_UH_UH { result = this.alu.MulUhUh(ra, rb) } else if op_code == instruction.MUL_UH_UL { result = this.alu.MulUhUl(ra, rb) } else if op_code == instruction.MUL_UL_UH { result = this.alu.MulUlUh(ra, rb) } else if op_code == instruction.MUL_UL_UL { result = this.alu.MulUlUl(ra, rb) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetMulNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRsubZrrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RsubRrrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid rsub RRRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRCI { err := errors.New("suffix is not ZRRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.RSUB { result, carry, overflow = this.alu.Sub(rb, ra) } else if op_code == instruction.RSUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(rb, ra, carry_flag) } else if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(ra, rb) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, rb, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, rb, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.RriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rri_op_code := instruction_.AddRriOpCodes()[op_code]; is_add_rri_op_code { this.ExecuteAddSRri(instruction_) } else if _, is_asr_rri_op_code := instruction_.AsrRriOpCodes()[op_code]; is_asr_rri_op_code { this.ExecuteAsrSRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAsrSRri(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRI && instruction_.Suffix() != instruction.U_RRI { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRric(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRric is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } op_code := instruction_.OpCode() if _, is_add_rrici_op_code := instruction_.AddRriciOpCodes()[op_code]; is_add_rrici_op_code { this.ExecuteAddSRrici(instruction_) } else if _, is_and_rrici_op_code := instruction_.AndRriciOpCodes()[op_code]; is_and_rrici_op_code { this.ExecuteAndSRrici(instruction_) } else if _, is_asr_rrici_op_code := instruction_.AsrRriciOpCodes()[op_code]; is_asr_rrici_op_code { this.ExecuteAsrSRrici(instruction_) } else if _, is_sub_rrici_op_code := instruction_.SubRriciOpCodes()[op_code]; is_sub_rrici_op_code { this.ExecuteSubSRrici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteAddSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AddRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid add RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, overflow = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Addc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetAddNzCc(instruction_, ra, result, carry, overflow) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteAndSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AndRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid and RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.AND { result = this.alu.And(ra, imm) } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteAsrSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.AsrRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid asr RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 op_code := instruction_.OpCode() if op_code == instruction.ASR { result = this.alu.Asr(ra, imm) } else if op_code == instruction.LSL { result = this.alu.Lsl(ra, imm) } else if op_code == instruction.LSL1 { result = this.alu.Lsl1(ra, imm) } else if op_code == instruction.LSL1X { result = this.alu.Lsl1x(ra, imm) } else if op_code == instruction.LSLX { result = this.alu.Lslx(ra, imm) } else if op_code == instruction.LSR { result = this.alu.Lsr(ra, imm) } else if op_code == instruction.LSR1 { result = this.alu.Lsr1(ra, imm) } else if op_code == instruction.LSR1X { result = this.alu.Lsr1x(ra, imm) } else if op_code == instruction.LSRX { result = this.alu.Lsrx(ra, imm) } else if op_code == instruction.ROL { result = this.alu.Rol(ra, imm) } else if op_code == instruction.ROR { result = this.alu.Ror(ra, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetImmShiftNzCc(instruction_, ra, result) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteSubSRrici(instruction_ *instruction.Instruction) { if _, found := instruction_.SubRriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sub RRICI op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRICI && instruction_.Suffix() != instruction.U_RRICI { err := errors.New("suffix is not S_RRICI nor U_RRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.ASR { result, carry, overflow = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(ra, imm, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, ra, imm, result, carry, overflow) var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRICI { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRICI { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRI nor U_RRI") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrif(instruction_ *instruction.Instruction) { if _, found := instruction_.RrifOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRIF op code") panic(err) } else if instruction_.Suffix() != instruction.S_RRIF && instruction_.Suffix() != instruction.U_RRIF { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.ADD { result, carry, _ = this.alu.Add(ra, imm) } else if op_code == instruction.ADDC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Addc(ra, imm, carry_flag) } else if op_code == instruction.AND { result = this.alu.And(ra, imm) carry = false } else if op_code == instruction.ANDN { result = this.alu.Andn(ra, imm) carry = false } else if op_code == instruction.NAND { result = this.alu.Nand(ra, imm) carry = false } else if op_code == instruction.NOR { result = this.alu.Nor(ra, imm) carry = false } else if op_code == instruction.NXOR { result = this.alu.Nxor(ra, imm) carry = false } else if op_code == instruction.OR { result = this.alu.Or(ra, imm) carry = false } else if op_code == instruction.ORN { result = this.alu.Orn(ra, imm) carry = false } else if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(ra, imm) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(ra, imm, carry_flag) } else if op_code == instruction.XOR { result = this.alu.Xor(ra, imm) carry = false } else if op_code == instruction.HASH { result = this.alu.Hash(ra, imm) carry = false } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() var even int64 var odd int64 if instruction_.Suffix() == instruction.S_RRIF { even, odd = this.alu.SignedExtension(result) } else if instruction_.Suffix() == instruction.U_RRIF { even, odd = this.alu.UnsignedExtension(result) } else { err := errors.New("suffix is not S_RRIF nor U_RRIF") panic(err) } thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrr(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrr is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrci is not yet implemented") panic(err) } func (this *Logic) ExecuteRr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } else if instruction_.Suffix() != instruction.RR { err := errors.New("suffix is not RR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } else if instruction_.Suffix() != instruction.RRC { err := errors.New("suffix is not RRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } op_code := instruction_.OpCode() if _, is_cao_rrci_op_code := instruction_.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { this.ExecuteCaoRrci(instruction_) } else if _, is_extsb_rrci_op_code := instruction_.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { this.ExecuteExtsbRrci(instruction_) } else if _, is_time_cfg_rrci_op_code := instruction_.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { this.ExecuteTimeCfgRrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteCaoRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.CaoRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid cao RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetCountNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteExtsbRrci(instruction_ *instruction.Instruction) { if _, found := instruction_.ExtsbRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid extsb RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RRCI { err := errors.New("suffix is not RRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteTimeCfgRrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteTimeCfgRrci is not yet implemented") panic(err) } func (this *Logic) ExecuteZr(instruction_ *instruction.Instruction) { if _, found := instruction_.RrOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RR op code") panic(err) } else if instruction_.Suffix() != instruction.ZR { err := errors.New("suffix is not ZR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteZrc(instruction_ *instruction.Instruction) { if _, found := instruction_.RrcOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZRC { err := errors.New("suffix is not RRC") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else if op_code == instruction.TIME_CFG { err := errors.New("TimeCfg is not yet implemented") panic(err) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogSetCc(instruction_, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.RrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } op_code := instruction_.OpCode() if _, is_cao_rrci_op_code := instruction_.CaoRrciOpCodes()[op_code]; is_cao_rrci_op_code { this.ExecuteCaoZrci(instruction_) } else if _, is_extsb_rrci_op_code := instruction_.ExtsbRrciOpCodes()[op_code]; is_extsb_rrci_op_code { this.ExecuteExtsbZrci(instruction_) } else if _, is_time_cfg_rrci_op_code := instruction_.TimeCfgRrciOpCodes()[op_code]; is_time_cfg_rrci_op_code { this.ExecuteTimeCfgZrci(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteCaoZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.CaoRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid cao RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.CAO { result = this.alu.Cao(ra) } else if op_code == instruction.CLO { result = this.alu.Clo(ra) } else if op_code == instruction.CLS { result = this.alu.Cls(ra) } else if op_code == instruction.CLZ { result = this.alu.Clz(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetCountNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteExtsbZrci(instruction_ *instruction.Instruction) { if _, found := instruction_.ExtsbRrciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid extsb RRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRCI { err := errors.New("suffix is not ZRCI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 op_code := instruction_.OpCode() if op_code == instruction.EXTSB { result = this.alu.Extsb(ra) } else if op_code == instruction.EXTSH { result = this.alu.Extsh(ra) } else if op_code == instruction.EXTUB { result = this.alu.Extub(ra) } else if op_code == instruction.EXTUH { result = this.alu.Extuh(ra) } else if op_code == instruction.SATS { result = this.alu.Sats(ra) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetLogNzCc(instruction_, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteTimeCfgZrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteTimeCfgZrci is not yet implemented") panic(err) } func (this *Logic) ExecuteSRr(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRr is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrci is not yet implemented") panic(err) } func (this *Logic) ExecuteDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.DrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } op_code := instruction_.OpCode() if _, is_div_step_drdici_op_code := instruction_.DivStepDrdiciOpCodes()[op_code]; is_div_step_drdici_op_code { this.ExecuteDivStepDrdici(instruction_) } else if _, is_mul_step_drdici_op_code := instruction_.MulStepDrdiciOpCodes()[op_code]; is_mul_step_drdici_op_code { this.ExecuteMulStepDrdici(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteDivStepDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.DivStepDrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid div_step DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), abi.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), abi.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() dbo_word := new(abi.Word) dbo_word.Init(mram_data_width) dbo_word.SetValue(dbo) ra_shift_value := this.alu.Lsl(ra, imm) ra_shift_word := new(abi.Word) ra_shift_word.Init(mram_data_width) ra_shift_word.SetValue(ra_shift_value) result, _, _ := this.alu.Sub(dbo, ra_shift_value) var dce int64 var dco int64 if dbo_word.Value(abi.UNSIGNED) >= ra_shift_word.Value(abi.UNSIGNED) { dce = this.alu.Lsl1(dbe, 1) dco = result } else { dce = this.alu.Lsl(dbe, 1) dco = thread.RegFile().ReadGpReg(instruction_.Dc().OddRegDescriptor(), abi.SIGNED) } thread.RegFile().ClearConditions() this.SetDivCc(instruction_, ra) thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dce) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dco) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, false) } func (this *Logic) ExecuteMulStepDrdici(instruction_ *instruction.Instruction) { if _, found := instruction_.MulStepDrdiciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid mul_step DRDICI op code") panic(err) } else if instruction_.Suffix() != instruction.DRDICI { err := errors.New("suffix is not DRDICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), abi.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), abi.SIGNED) imm := instruction_.Imm().Value() result1 := this.alu.Lsr(dbe, 1) result2, _, _ := this.alu.Sub(this.alu.And(dbe, 1), 1) var dco int64 if result2 == 0 { dco, _, _ = this.alu.Add(dbo, this.alu.Lsl(ra, imm)) } else { dco = thread.RegFile().ReadGpReg(instruction_.Dc().OddRegDescriptor(), abi.SIGNED) } dce := this.alu.Lsr(dbe, 1) thread.RegFile().ClearConditions() this.SetBootCc(instruction_, ra, result1) thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dce) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dco) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result1, false) } func (this *Logic) ExecuteRrri(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRI { err := errors.New("suffix is not RRRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRrrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.RRRICI { err := errors.New("suffix is not RRRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetDivNzCc(instruction_, ra) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrri(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRI { err := errors.New("suffix is not ZRRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZrrici(instruction_ *instruction.Instruction) { if _, found := instruction_.RrriciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RRRICI op code") panic(err) } else if instruction_.Suffix() != instruction.ZRRICI { err := errors.New("suffix is not ZRRICI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.LSL_ADD { result, carry, _ = this.alu.LslAdd(ra, rb, imm) } else if op_code == instruction.LSL_SUB { result, carry, _ = this.alu.LslSub(ra, rb, imm) } else if op_code == instruction.LSR_ADD { result, carry, _ = this.alu.LsrAdd(ra, rb, imm) } else if op_code == instruction.ROL_ADD { result, carry, _ = this.alu.RolAdd(ra, rb, imm) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetDivNzCc(instruction_, ra) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRrri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrri is not yet implemented") panic(err) } func (this *Logic) ExecuteSRrrici(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRrrici is not yet implemented") panic(err) } func (this *Logic) ExecuteRir(instruction_ *instruction.Instruction) { if _, found := instruction_.RirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } else if instruction_.Suffix() != instruction.RIR { err := errors.New("suffix is not RIR") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRirc(instruction_ *instruction.Instruction) { if _, found := instruction_.RircOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } else if instruction_.Suffix() != instruction.RIRC { err := errors.New("suffix is not RIRC") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, imm, ra, result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WriteGpReg(instruction_.Rc(), 1) } else { thread.RegFile().WriteGpReg(instruction_.Rc(), 0) } thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteRirci(instruction_ *instruction.Instruction) { if _, found := instruction_.RirciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } else if instruction_.Suffix() != instruction.RIRCI { err := errors.New("suffix is not RIRCI") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, imm, ra, result, carry, overflow) thread.RegFile().WriteGpReg(instruction_.Rc(), result) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZir(instruction_ *instruction.Instruction) { if _, found := instruction_.RirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIR op code") panic(err) } else if instruction_.Suffix() != instruction.ZIR { err := errors.New("suffix is not ZIR") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZirc(instruction_ *instruction.Instruction) { if _, found := instruction_.RircOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRC op code") panic(err) } else if instruction_.Suffix() != instruction.ZIRC { err := errors.New("suffix is not ZIRC") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, _ = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, _ = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubSetCc(instruction_, imm, ra, result) thread.RegFile().IncrementPcReg() this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteZirci(instruction_ *instruction.Instruction) { if _, found := instruction_.RirciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid RIRCI op code") panic(err) } else if instruction_.Suffix() != instruction.ZIRCI { err := errors.New("suffix is not ZIRCI") panic(err) } thread := this.scoreboard[instruction_] imm := instruction_.Imm().Value() ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) var result int64 var carry bool var overflow bool op_code := instruction_.OpCode() if op_code == instruction.SUB { result, carry, overflow = this.alu.Sub(imm, ra) } else if op_code == instruction.SUBC { carry_flag := thread.RegFile().ReadFlagReg(instruction.CARRY) result, carry, overflow = this.alu.Subc(imm, ra, carry_flag) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() this.SetSubNzCc(instruction_, imm, ra, result, carry, overflow) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } this.SetFlags(instruction_, result, carry) } func (this *Logic) ExecuteSRirc(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRirc is not yet implemented") panic(err) } func (this *Logic) ExecuteSRirci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRirci is not yet implemented") panic(err) } func (this *Logic) ExecuteR(instruction_ *instruction.Instruction) { err := errors.New("ExecuteR is not yet implemented") panic(err) } func (this *Logic) ExecuteRci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteRci is not yet implemented") panic(err) } func (this *Logic) ExecuteZ(instruction_ *instruction.Instruction) { if _, found := instruction_.ROpCodes()[instruction_.OpCode()]; !found && instruction_.OpCode() != instruction.NOP { err := errors.New("op code is not a valid R op code") panic(err) } else if instruction_.Suffix() != instruction.Z { err := errors.New("suffix is not Z") panic(err) } thread := this.scoreboard[instruction_] thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteZci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteZci is not yet implemented") panic(err) } func (this *Logic) ExecuteSR(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSR is not yet implemented") panic(err) } func (this *Logic) ExecuteSRci(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSRci is not yet implemented") panic(err) } func (this *Logic) ExecuteCi(instruction_ *instruction.Instruction) { if _, found := instruction_.CiOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid CI op code") panic(err) } else if instruction_.Suffix() != instruction.CI { err := errors.New("suffix is not CI") panic(err) } thread := this.scoreboard[instruction_] this.thread_scheduler.Sleep(thread.ThreadId()) thread.RegFile().ClearConditions() if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteI(instruction_ *instruction.Instruction) { err := errors.New("ExecuteI is not yet implemented") panic(err) } func (this *Logic) ExecuteDdci(instruction_ *instruction.Instruction) { if _, found := instruction_.DdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } op_code := instruction_.OpCode() if _, is_movd_ddci_op_code := instruction_.MovdDdciOpCodes()[op_code]; is_movd_ddci_op_code { this.ExecuteMovdDdci(instruction_) } else if _, is_swapd_ddci_op_code := instruction_.SwapdDdciOpCodes()[op_code]; is_swapd_ddci_op_code { this.ExecuteSwapdDdciRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteMovdDdci(instruction_ *instruction.Instruction) { if _, found := instruction_.MovdDdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid movd DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } thread := this.scoreboard[instruction_] dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), abi.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), abi.SIGNED) thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dbe) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dbo) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteSwapdDdciRri(instruction_ *instruction.Instruction) { if _, found := instruction_.SwapdDdciOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid movd DDCI op code") panic(err) } else if instruction_.Suffix() != instruction.DDCI { err := errors.New("suffix is not DDCI") panic(err) } thread := this.scoreboard[instruction_] dbe := thread.RegFile().ReadGpReg(instruction_.Db().EvenRegDescriptor(), abi.SIGNED) dbo := thread.RegFile().ReadGpReg(instruction_.Db().OddRegDescriptor(), abi.SIGNED) thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Dc().EvenRegDescriptor(), dbo) thread.RegFile().WriteGpReg(instruction_.Dc().OddRegDescriptor(), dbe) if thread.RegFile().ReadConditionReg(instruction_.Condition()) { thread.RegFile().WritePcReg(instruction_.Pc().Value()) } else { thread.RegFile().IncrementPcReg() } } func (this *Logic) ExecuteErri(instruction_ *instruction.Instruction) { if _, found := instruction_.ErriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERRI op code") panic(err) } else if instruction_.Suffix() != instruction.ERRI { err := errors.New("suffix is not ERRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) off := instruction_.Off().Value() address, _, _ := this.alu.Add(ra, off) var result int64 op_code := instruction_.OpCode() if op_code == instruction.LBS { result = this.operand_collector.Lbs(address) } else if op_code == instruction.LBU { result = this.operand_collector.Lbu(address) } else if op_code == instruction.LHS { result = this.operand_collector.Lhs(address) } else if op_code == instruction.LHU { result = this.operand_collector.Lhu(address) } else if op_code == instruction.LW { result = this.operand_collector.Lw(address) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WriteGpReg(instruction_.Rc(), result) thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteSErri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteSErri is not yet implemented") panic(err) } func (this *Logic) ExecuteEdri(instruction_ *instruction.Instruction) { if _, found := instruction_.EdriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid EDRI op code") panic(err) } else if instruction_.Suffix() != instruction.EDRI { err := errors.New("suffix is not EDRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) off := instruction_.Off().Value() address, _, _ := this.alu.Add(ra, off) var even int64 var odd int64 op_code := instruction_.OpCode() if op_code == instruction.LD { even, odd = this.operand_collector.Ld(address) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().WritePairReg(instruction_.Dc(), even, odd) thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErii(instruction_ *instruction.Instruction) { if _, found := instruction_.EriiOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERII op code") panic(err) } else if instruction_.Suffix() != instruction.ERII { err := errors.New("suffix is not ERII") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) off := instruction_.Off().Value() imm := instruction_.Imm().Value() address, _, _ := this.alu.Add(ra, off) op_code := instruction_.OpCode() if op_code == instruction.SB { this.operand_collector.Sb(address, imm) } else if op_code == instruction.SB_ID { this.operand_collector.Sb(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SH { this.operand_collector.Sh(address, imm) } else if op_code == instruction.SH_ID { this.operand_collector.Sh(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SW { this.operand_collector.Sw(address, imm) } else if op_code == instruction.SW_ID { this.operand_collector.Sw(address, this.alu.Or(int64(thread.ThreadId()), imm)) } else if op_code == instruction.SD { even, odd := this.alu.UnsignedExtension(imm) this.operand_collector.Sd(address, even, odd) } else if op_code == instruction.SD_ID { even, odd := this.alu.UnsignedExtension(this.alu.Or(int64(thread.ThreadId()), imm)) this.operand_collector.Sd(address, even, odd) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErir(instruction_ *instruction.Instruction) { if _, found := instruction_.ErirOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERIR op code") panic(err) } else if instruction_.Suffix() != instruction.ERIR { err := errors.New("suffix is not ERIR") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) off := instruction_.Off().Value() rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) address, _, _ := this.alu.Add(ra, off) config_loader := new(misc.ConfigLoader) config_loader.Init() rb_word := new(abi.Word) rb_word.Init(config_loader.MramDataWidth()) rb_word.SetValue(rb) op_code := instruction_.OpCode() if op_code == instruction.SB { this.operand_collector.Sb(address, rb_word.BitSlice(abi.UNSIGNED, 0, 8)) } else if op_code == instruction.SH { this.operand_collector.Sh(address, rb_word.BitSlice(abi.UNSIGNED, 0, 16)) } else if op_code == instruction.SW { this.operand_collector.Sw(address, rb_word.BitSlice(abi.UNSIGNED, 0, 32)) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteErid(instruction_ *instruction.Instruction) { if _, found := instruction_.EridOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ERID op code") panic(err) } else if instruction_.Suffix() != instruction.ERID { err := errors.New("suffix is not ERID") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) off := instruction_.Off().Value() even, odd := thread.RegFile().ReadPairReg(instruction_.Db(), abi.SIGNED) address, _, _ := this.alu.Add(ra, off) op_code := instruction_.OpCode() if op_code == instruction.SD { this.operand_collector.Sd(address, even, odd) } else { err := errors.New("op code is not valid") panic(err) } thread.RegFile().ClearConditions() thread.RegFile().IncrementPcReg() } func (this *Logic) ExecuteDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.DmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } op_code := instruction_.OpCode() if _, is_ldma_dma_rri_op_code := instruction_.LdmaDmaRriOpCodes()[op_code]; is_ldma_dma_rri_op_code { this.ExecuteLdmaDmaRri(instruction_) } else if _, is_ldmai_dma_rri_op_code := instruction_.LdmaiDmaRriOpCodes()[op_code]; is_ldmai_dma_rri_op_code { this.ExecuteLdmaiDmaRri(instruction_) } else if _, is_sdma_dma_rri_op_code := instruction_.SdmaDmaRriOpCodes()[op_code]; is_sdma_dma_rri_op_code { this.ExecuteSdmaDmaRri(instruction_) } else { err := errors.New("op code is not valid") panic(err) } } func (this *Logic) ExecuteLdmaDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.LdmaDmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid ldma DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() wram_end_address := config_loader.WramOffset() + config_loader.WramSize() wram_end_address_width := int(math.Floor(math.Log2(float64(wram_end_address))) + 1) wram_mask := this.Pow2(wram_end_address_width) - 1 wram_address := this.alu.And(ra, wram_mask) mram_end_address := config_loader.MramOffset() + config_loader.MramSize() mram_end_address_width := int(math.Floor(math.Log2(float64(mram_end_address))) + 1) mram_mask := this.Pow2(mram_end_address_width) - 1 mram_address := this.alu.And(rb, mram_mask) size := (1 + this.alu.And(imm+this.alu.And(this.alu.Lsr(ra, 24), 255), 255)) * this.min_access_granularity this.dma.TransferFromMramToWram(wram_address, mram_address, size, instruction_) thread.RegFile().ClearConditions() } func (this *Logic) ExecuteLdmaiDmaRri(instruction_ *instruction.Instruction) { err := errors.New("ExecuteLdmaiDmaRri is not yet implemented") panic(err) } func (this *Logic) ExecuteSdmaDmaRri(instruction_ *instruction.Instruction) { if _, found := instruction_.SdmaDmaRriOpCodes()[instruction_.OpCode()]; !found { err := errors.New("op code is not a valid sdma DMA_RRI op code") panic(err) } else if instruction_.Suffix() != instruction.DMA_RRI { err := errors.New("suffix is not DMA_RRI") panic(err) } thread := this.scoreboard[instruction_] ra := thread.RegFile().ReadSrcReg(instruction_.Ra(), abi.SIGNED) rb := thread.RegFile().ReadSrcReg(instruction_.Rb(), abi.SIGNED) imm := instruction_.Imm().Value() config_loader := new(misc.ConfigLoader) config_loader.Init() wram_end_address := config_loader.WramOffset() + config_loader.WramSize() wram_end_address_width := int(math.Floor(math.Log2(float64(wram_end_address))) + 1) wram_mask := this.Pow2(wram_end_address_width) - 1 wram_address := this.alu.And(ra, wram_mask) mram_end_address := config_loader.MramOffset() + config_loader.MramSize() mram_end_address_width := int(math.Floor(math.Log2(float64(mram_end_address))) + 1) mram_mask := this.Pow2(mram_end_address_width) - 1 mram_address := this.alu.And(rb, mram_mask) size := (1 + this.alu.And(imm+this.alu.And(this.alu.Lsr(ra, 24), 255), 255)) * this.min_access_granularity this.dma.TransferFromWramToMram(wram_address, mram_address, size, instruction_) thread.RegFile().ClearConditions() } func (this *Logic) SetAcquireCc(instruction_ *instruction.Instruction, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } } func (this *Logic) SetAddNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() result_word := new(abi.Word) result_word.Init(config_loader.MramDataWidth()) result_word.SetValue(result) if result_word.Bit(6) { thread.RegFile().SetCondition(cc.NC5) } if result_word.Bit(7) { thread.RegFile().SetCondition(cc.NC6) } if result_word.Bit(8) { thread.RegFile().SetCondition(cc.NC7) } if result_word.Bit(9) { thread.RegFile().SetCondition(cc.NC8) } if result_word.Bit(10) { thread.RegFile().SetCondition(cc.NC9) } if result_word.Bit(11) { thread.RegFile().SetCondition(cc.NC10) } if result_word.Bit(12) { thread.RegFile().SetCondition(cc.NC11) } if result_word.Bit(13) { thread.RegFile().SetCondition(cc.NC12) } if result_word.Bit(14) { thread.RegFile().SetCondition(cc.NC13) } if result_word.Bit(15) { thread.RegFile().SetCondition(cc.NC14) } } func (this *Logic) SetBootCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetCountNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() if result == int64(config_loader.MramDataWidth()) { thread.RegFile().SetCondition(cc.MAX) } else { thread.RegFile().SetCondition(cc.NMAX) } } func (this *Logic) SetDivCc(instruction_ *instruction.Instruction, operand1 int64) { thread := this.scoreboard[instruction_] if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetDivNzCc(instruction_ *instruction.Instruction, operand1 int64) { thread := this.scoreboard[instruction_] if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetExtSubSetCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) if word1.Value(abi.UNSIGNED) < word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.LTU) } if word1.Value(abi.UNSIGNED) <= word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.LEU) } if word1.Value(abi.UNSIGNED) > word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.GTU) } if word1.Value(abi.UNSIGNED) >= word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.GEU) } if word1.Value(abi.SIGNED) < word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.LTS) } if word1.Value(abi.SIGNED) <= word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.LES) } if word1.Value(abi.SIGNED) > word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.GTS) } if word1.Value(abi.SIGNED) >= word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.GES) } if carry || thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XLEU) } if carry || !thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XGTU) } if thread.RegFile().ReadFlagReg(instruction.ZERO) && (result < 0 || overflow) { thread.RegFile().SetCondition(cc.XLES) } if !thread.RegFile().ReadFlagReg(instruction.ZERO) && (result >= 0 || overflow) { thread.RegFile().SetCondition(cc.XGTS) } } func (this *Logic) SetImmShiftNzCc( instruction_ *instruction.Instruction, operand1 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if result%2 == 0 { thread.RegFile().SetCondition(cc.E) } else { thread.RegFile().SetCondition(cc.O) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1%2 == 0 { thread.RegFile().SetCondition(cc.SE) } else { thread.RegFile().SetCondition(cc.SO) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetLogNzCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } } func (this *Logic) SetLogSetCc(instruction_ *instruction.Instruction, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } } func (this *Logic) SetMulNzCc(instruction_ *instruction.Instruction, operand1 int64, result int64) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == 0 { thread.RegFile().SetCondition(cc.SZ) } else { thread.RegFile().SetCondition(cc.SNZ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } if result < 256 { thread.RegFile().SetCondition(cc.SMALL) } else { thread.RegFile().SetCondition(cc.LARGE) } } func (this *Logic) SetSubNzCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, carry bool, overflow bool, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if carry { thread.RegFile().SetCondition(cc.C) } else { thread.RegFile().SetCondition(cc.NC) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if overflow { thread.RegFile().SetCondition(cc.OV) } else { thread.RegFile().SetCondition(cc.NOV) } if result >= 0 { thread.RegFile().SetCondition(cc.PL) } else { thread.RegFile().SetCondition(cc.MI) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } if operand1 >= 0 { thread.RegFile().SetCondition(cc.SPL) } else { thread.RegFile().SetCondition(cc.SMI) } config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_width := config_loader.MramDataWidth() word1 := new(abi.Word) word1.Init(mram_data_width) word1.SetValue(operand1) word2 := new(abi.Word) word2.Init(mram_data_width) word2.SetValue(operand2) if word1.Value(abi.UNSIGNED) < word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.LTU) } if word1.Value(abi.UNSIGNED) <= word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.LEU) } if word1.Value(abi.UNSIGNED) > word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.GTU) } if word1.Value(abi.UNSIGNED) >= word2.Value(abi.UNSIGNED) { thread.RegFile().SetCondition(cc.GEU) } if word1.Value(abi.SIGNED) < word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.LTS) } if word1.Value(abi.SIGNED) <= word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.LES) } if word1.Value(abi.SIGNED) > word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.GTS) } if word1.Value(abi.SIGNED) >= word2.Value(abi.SIGNED) { thread.RegFile().SetCondition(cc.GES) } if carry || thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XLEU) } if carry || !thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XGTU) } if thread.RegFile().ReadFlagReg(instruction.ZERO) && (result < 0 || overflow) { thread.RegFile().SetCondition(cc.XLES) } if !thread.RegFile().ReadFlagReg(instruction.ZERO) && (result >= 0 || overflow) { thread.RegFile().SetCondition(cc.XGTS) } } func (this *Logic) SetSubSetCc( instruction_ *instruction.Instruction, operand1 int64, operand2 int64, result int64, ) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetCondition(cc.Z) } else { thread.RegFile().SetCondition(cc.NZ) } if result == 0 && thread.RegFile().ReadFlagReg(instruction.ZERO) { thread.RegFile().SetCondition(cc.XZ) } else { thread.RegFile().SetCondition(cc.XNZ) } if operand1 == operand2 { thread.RegFile().SetCondition(cc.EQ) } else { thread.RegFile().SetCondition(cc.NEQ) } } func (this *Logic) SetFlags(instruction_ *instruction.Instruction, result int64, carry bool) { thread := this.scoreboard[instruction_] if result == 0 { thread.RegFile().SetFlag(instruction.ZERO) } else { thread.RegFile().ClearFlag(instruction.ZERO) } if carry { thread.RegFile().SetFlag(instruction.CARRY) } else { thread.RegFile().ClearFlag(instruction.CARRY) } } func (this *Logic) Pow2(exponent int) int64 { if exponent < 0 { err := errors.New("exponent < 0") panic(err) } value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } func (this *Logic) PrintRegFile(thread *Thread) string { config_loader := new(misc.ConfigLoader) config_loader.Init() lines := "" for i := 0; i < config_loader.NumGpRegisters(); i++ { gp_reg_descriptor := new(reg_descriptor.GpRegDescriptor) gp_reg_descriptor.Init(i) lines += fmt.Sprintf( "r%d: %d\n", i, thread.RegFile().ReadGpReg(gp_reg_descriptor, abi.SIGNED), ) } return lines } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/operand_collector.go ================================================ package logic import ( "errors" "uPIMulator/src/device/abi" "uPIMulator/src/device/simulator/dpu/sram" "uPIMulator/src/encoding" ) type OperandCollector struct { wram *sram.Wram } func (this *OperandCollector) Init() { this.wram = nil } func (this *OperandCollector) Fini() { } func (this *OperandCollector) ConnectWram(wram *sram.Wram) { if this.wram != nil { err := errors.New("wram is already set") panic(err) } this.wram = wram } func (this *OperandCollector) Lbs(address int64) int64 { byte_stream := this.wram.Read(address, 1) value := int64(byte_stream.Get(0)) word_ := new(abi.Word) word_.Init(8) word_.SetValue(value) return word_.Value(abi.SIGNED) } func (this *OperandCollector) Lbu(address int64) int64 { byte_stream := this.wram.Read(address, 1) value := int64(byte_stream.Get(0)) word_ := new(abi.Word) word_.Init(8) word_.SetValue(value) return word_.Value(abi.UNSIGNED) } func (this *OperandCollector) Lhs(address int64) int64 { word_ := new(abi.Word) word_.Init(16) word_.SetBitSlice(0, 8, this.Lbs(address)) word_.SetBitSlice(8, 16, this.Lbs(address+1)) return word_.Value(abi.SIGNED) } func (this *OperandCollector) Lhu(address int64) int64 { word_ := new(abi.Word) word_.Init(16) word_.SetBitSlice(0, 8, this.Lbu(address)) word_.SetBitSlice(8, 16, this.Lbu(address+1)) return word_.Value(abi.UNSIGNED) } func (this *OperandCollector) Lw(address int64) int64 { word_ := new(abi.Word) word_.Init(32) word_.SetBitSlice(0, 8, this.Lbu(address)) word_.SetBitSlice(8, 16, this.Lbu(address+1)) word_.SetBitSlice(16, 24, this.Lbu(address+2)) word_.SetBitSlice(24, 32, this.Lbu(address+3)) return word_.Value(abi.UNSIGNED) } func (this *OperandCollector) Ld(address int64) (int64, int64) { return this.Lw(address + 4), this.Lw(address) } func (this *OperandCollector) Sb(address int64, value int64) { word_ := new(abi.Word) word_.Init(8) word_.SetValue(value) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(word_.Value(abi.UNSIGNED))) this.wram.Write(address, 1, byte_stream) } func (this *OperandCollector) Sh(address int64, value int64) { word_ := new(abi.Word) word_.Init(16) word_.SetValue(value) this.Sb(address, word_.BitSlice(abi.UNSIGNED, 0, 8)) this.Sb(address+1, word_.BitSlice(abi.UNSIGNED, 8, 16)) } func (this *OperandCollector) Sw(address int64, value int64) { word_ := new(abi.Word) word_.Init(32) word_.SetValue(value) this.Sb(address, word_.BitSlice(abi.UNSIGNED, 0, 8)) this.Sb(address+1, word_.BitSlice(abi.UNSIGNED, 8, 16)) this.Sb(address+2, word_.BitSlice(abi.UNSIGNED, 16, 24)) this.Sb(address+3, word_.BitSlice(abi.UNSIGNED, 24, 32)) } func (this *OperandCollector) Sd(address int64, even int64, odd int64) { this.Sw(address+4, even) this.Sw(address, odd) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/pipeline.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/misc" ) type Pipeline struct { num_pipeline_stages int input_q *InstructionQ wait_q *InstructionQ ready_q *InstructionQ } func (this *Pipeline) Init(command_line_parser *misc.CommandLineParser) { this.num_pipeline_stages = int(command_line_parser.IntParameter("num_pipeline_stages")) this.input_q = new(InstructionQ) this.input_q.Init(1, 0) this.wait_q = new(InstructionQ) this.wait_q.Init(this.num_pipeline_stages-1, 0) for this.wait_q.CanPush(1) { this.wait_q.Push(nil) } this.ready_q = new(InstructionQ) this.ready_q.Init(1, 0) for this.ready_q.CanPush(1) { this.ready_q.Push(nil) } } func (this *Pipeline) Fini() { this.input_q.Fini() for this.wait_q.CanPop(1) { if this.wait_q.Pop() != nil { err := errors.New("wait queue is not empty") panic(err) } } this.wait_q.Fini() for this.ready_q.CanPop(1) { if this.ready_q.Pop() != nil { err := errors.New("ready queue is not empty") panic(err) } } this.ready_q.Fini() } func (this *Pipeline) IsEmpty() bool { return this.IsInputQEmpty() && this.IsWaitQEmpty() && this.IsReadyQEmpty() } func (this *Pipeline) IsInputQEmpty() bool { return this.input_q.IsEmpty() } func (this *Pipeline) IsWaitQEmpty() bool { if this.wait_q.IsEmpty() { return true } else { for i := 0; this.wait_q.CanPop(i + 1); i++ { instruction_, _ := this.wait_q.Front(i) if instruction_ != nil { return false } } return true } } func (this *Pipeline) IsReadyQEmpty() bool { if this.ready_q.IsEmpty() { return true } else { for i := 0; this.ready_q.CanPop(i + 1); i++ { instruction_, _ := this.ready_q.Front(i) if instruction_ != nil { return false } } return true } } func (this *Pipeline) CanPush() bool { return this.input_q.CanPush(1) } func (this *Pipeline) Push(instruction_ *instruction.Instruction) { if !this.CanPush() { err := errors.New("pipeline cannot be pushed") panic(err) } else if instruction_ == nil { err := errors.New("instruction == nil") panic(err) } this.input_q.Push(instruction_) } func (this *Pipeline) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Pipeline) Pop() *instruction.Instruction { if !this.CanPop() { err := errors.New("pipeline cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Pipeline) Cycle() { this.ServiceInputQ() this.ServiceWaitQ() this.input_q.Cycle() this.wait_q.Cycle() this.ready_q.Cycle() } func (this *Pipeline) ServiceInputQ() { if this.input_q.CanPop(1) && this.wait_q.CanPush(1) { instruction_ := this.input_q.Pop() this.wait_q.Push(instruction_) } else if this.wait_q.CanPush(1) { this.wait_q.Push(nil) } } func (this *Pipeline) ServiceWaitQ() { if this.wait_q.CanPop(1) && this.ready_q.CanPush(1) { instruction_ := this.wait_q.Pop() this.ready_q.Push(instruction_) } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/reg_set.go ================================================ package logic import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" ) type RegSet struct { thread_id int prev_write_gp_reg_set map[*reg_descriptor.GpRegDescriptor]bool cur_read_gp_reg_set map[*reg_descriptor.GpRegDescriptor]bool } func (this *RegSet) Init(thread_id int) { if thread_id < 0 { err := errors.New("thread ID < 0") panic(err) } this.thread_id = thread_id this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } func (this *RegSet) ThreadId() int { return this.thread_id } func (this *RegSet) CollectReadGpRegs(instruction_ *instruction.Instruction) { suffix := instruction_.Suffix() if suffix == instruction.RICI || suffix == instruction.RRI || suffix == instruction.RRIC || suffix == instruction.RRICI || suffix == instruction.RRIF || suffix == instruction.ZRI || suffix == instruction.ZRIC || suffix == instruction.ZRICI || suffix == instruction.ZRIF || suffix == instruction.S_RRI || suffix == instruction.U_RRI || suffix == instruction.S_RRIC || suffix == instruction.U_RRIC || suffix == instruction.S_RRICI || suffix == instruction.U_RRICI || suffix == instruction.S_RRIF || suffix == instruction.U_RRIF || suffix == instruction.RR || suffix == instruction.RRC || suffix == instruction.RRCI || suffix == instruction.ZR || suffix == instruction.ZRC || suffix == instruction.ZRCI || suffix == instruction.S_RR || suffix == instruction.U_RR || suffix == instruction.S_RRC || suffix == instruction.U_RRC || suffix == instruction.S_RRCI || suffix == instruction.U_RRCI || suffix == instruction.RIR || suffix == instruction.RIRC || suffix == instruction.RIRCI || suffix == instruction.ZIR || suffix == instruction.ZIRC || suffix == instruction.ZIRCI || suffix == instruction.S_RIRC || suffix == instruction.U_RIRC || suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI || suffix == instruction.ERRI || suffix == instruction.S_ERRI || suffix == instruction.U_ERRI || suffix == instruction.EDRI || suffix == instruction.ERII { if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true } else { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } } else if suffix == instruction.RRR || suffix == instruction.RRRC || suffix == instruction.RRRCI || suffix == instruction.ZRR || suffix == instruction.ZRRC || suffix == instruction.ZRRCI || suffix == instruction.S_RRR || suffix == instruction.U_RRR || suffix == instruction.S_RRRC || suffix == instruction.U_RRRC || suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI || suffix == instruction.RRRI || suffix == instruction.RRRICI || suffix == instruction.ZRRI || suffix == instruction.ZRRICI || suffix == instruction.S_RRRI || suffix == instruction.U_RRRI || suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI || suffix == instruction.ERIR || suffix == instruction.DMA_RRI { if instruction_.Ra().IsGpRegDescriptor() && instruction_.Rb().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Rb().GpRegDescriptor()] = true } else if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true } else if instruction_.Rb().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Rb().GpRegDescriptor()] = true } else { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } } else if suffix == instruction.DRDICI || suffix == instruction.ERID { if instruction_.Ra().IsGpRegDescriptor() { this.cur_read_gp_reg_set[instruction_.Ra().GpRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } else { this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } } else if suffix == instruction.R || suffix == instruction.RCI || suffix == instruction.Z || suffix == instruction.ZCI || suffix == instruction.S_R || suffix == instruction.U_R || suffix == instruction.S_RCI || suffix == instruction.U_RCI || suffix == instruction.CI || suffix == instruction.I { this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } else if suffix == instruction.DDCI { this.cur_read_gp_reg_set[instruction_.Db().EvenRegDescriptor()] = true this.cur_read_gp_reg_set[instruction_.Db().OddRegDescriptor()] = true } else { err := errors.New("suffix is not valid") panic(err) } } func (this *RegSet) CollectWriteGpRegs(instruction_ *instruction.Instruction) { suffix := instruction_.Suffix() if suffix == instruction.RICI || suffix == instruction.ZRI || suffix == instruction.ZRIC || suffix == instruction.ZRICI || suffix == instruction.ZRIF || suffix == instruction.ZRR || suffix == instruction.ZRRC || suffix == instruction.ZRRCI || suffix == instruction.ZR || suffix == instruction.ZRC || suffix == instruction.ZRCI || suffix == instruction.ZRRI || suffix == instruction.ZRRICI || suffix == instruction.ZIR || suffix == instruction.ZIRC || suffix == instruction.ZIRCI || suffix == instruction.Z || suffix == instruction.ZCI || suffix == instruction.CI || suffix == instruction.I || suffix == instruction.ERII || suffix == instruction.ERIR || suffix == instruction.ERID || suffix == instruction.DMA_RRI { this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } else if suffix == instruction.RRI || suffix == instruction.RRIC || suffix == instruction.RRICI || suffix == instruction.RRIF || suffix == instruction.RRR || suffix == instruction.RRRC || suffix == instruction.RRRCI || suffix == instruction.RR || suffix == instruction.RRC || suffix == instruction.RRCI || suffix == instruction.RRRI || suffix == instruction.RRRICI || suffix == instruction.RIR || suffix == instruction.RIRC || suffix == instruction.RIRCI || suffix == instruction.R || suffix == instruction.RCI || suffix == instruction.ERRI { this.prev_write_gp_reg_set[instruction_.Rc()] = true } else if suffix == instruction.S_RRI || suffix == instruction.U_RRI || suffix == instruction.S_RRIC || suffix == instruction.U_RRIC || suffix == instruction.S_RRICI || suffix == instruction.U_RRICI || suffix == instruction.S_RRIF || suffix == instruction.U_RRIF || suffix == instruction.S_RRR || suffix == instruction.U_RRR || suffix == instruction.S_RRRC || suffix == instruction.U_RRRC || suffix == instruction.S_RRRCI || suffix == instruction.U_RRRCI || suffix == instruction.S_RR || suffix == instruction.U_RR || suffix == instruction.S_RRC || suffix == instruction.U_RRC || suffix == instruction.S_RRCI || suffix == instruction.U_RRCI || suffix == instruction.DRDICI || suffix == instruction.S_RRRI || suffix == instruction.U_RRRI || suffix == instruction.S_RRRICI || suffix == instruction.U_RRRICI || suffix == instruction.S_RIRC || suffix == instruction.U_RIRC || suffix == instruction.S_RIRCI || suffix == instruction.U_RIRCI || suffix == instruction.S_R || suffix == instruction.U_R || suffix == instruction.DDCI || suffix == instruction.S_ERRI || suffix == instruction.U_ERRI || suffix == instruction.EDRI { this.prev_write_gp_reg_set[instruction_.Dc().EvenRegDescriptor()] = true this.prev_write_gp_reg_set[instruction_.Dc().OddRegDescriptor()] = true } else { err := errors.New("suffix is not valid") panic(err) } } func (this *RegSet) Clear() { this.prev_write_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) this.cur_read_gp_reg_set = make(map[*reg_descriptor.GpRegDescriptor]bool) } func (this *RegSet) RegIndices() map[int]bool { reg_indices := make(map[int]bool) for gp_reg_descriptor, _ := range this.prev_write_gp_reg_set { reg_indices[gp_reg_descriptor.Index()] = true } for gp_reg_descriptor, _ := range this.cur_read_gp_reg_set { reg_indices[gp_reg_descriptor.Index()] = true } return reg_indices } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/thread.go ================================================ package logic import ( "errors" "uPIMulator/src/device/simulator/dpu/reg" "uPIMulator/src/misc" ) type ThreadState int const ( EMBRYO ThreadState = iota RUNNABLE SLEEP BLOCK ZOMBIE ) type Thread struct { thread_id int thread_state ThreadState reg_file *reg.RegFile issue_cycle int64 } func (this *Thread) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() if thread_id < 0 { err := errors.New("thread ID < 0") panic(err) } else if thread_id >= config_loader.MaxNumTasklets() { err := errors.New("thread ID >= max number of tasklets") panic(err) } this.thread_id = thread_id this.thread_state = EMBRYO this.reg_file = new(reg.RegFile) this.reg_file.Init(thread_id) this.issue_cycle = 0 } func (this *Thread) Fini() { if this.thread_state != EMBRYO { err := errors.New("thread state is not zombie") panic(err) } } func (this *Thread) ThreadId() int { return this.thread_id } func (this *Thread) ThreadState() ThreadState { return this.thread_state } func (this *Thread) SetThreadState(thread_state ThreadState) { this.thread_state = thread_state } func (this *Thread) RegFile() *reg.RegFile { return this.reg_file } func (this *Thread) IssueCycle() int64 { return this.issue_cycle } func (this *Thread) IncrementIssueCycle() { this.issue_cycle++ } func (this *Thread) ResetIssueCycle() { this.issue_cycle = 0 } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/thread_q.go ================================================ package logic import ( "errors" ) type ThreadQ struct { size int timer int64 threads []*Thread cycles []int64 } func (this *ThreadQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.threads = make([]*Thread, 0) this.cycles = make([]int64, 0) } func (this *ThreadQ) Fini() { if !this.IsEmpty() { err := errors.New("thread queue is not empty") panic(err) } } func (this *ThreadQ) Size() int { return this.size } func (this *ThreadQ) Length() int { return len(this.threads) } func (this *ThreadQ) Timer() int64 { return this.timer } func (this *ThreadQ) IsEmpty() bool { return len(this.threads) == 0 } func (this *ThreadQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.threads) >= num_items } else { return true } } func (this *ThreadQ) Push(thread *Thread) { if !this.CanPush(1) { err := errors.New("thread queue cannot be pushed") panic(err) } this.threads = append(this.threads, thread) this.cycles = append(this.cycles, this.timer) } func (this *ThreadQ) PushWithTimer(thread *Thread, timer int64) { if !this.CanPush(1) { err := errors.New("thread queue cannot be pushed") panic(err) } this.threads = append(this.threads, thread) this.cycles = append(this.cycles, timer) } func (this *ThreadQ) CanPop(num_items int) bool { if len(this.threads) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *ThreadQ) Pop() *Thread { if !this.CanPop(1) { err := errors.New("thread queue cannot be popped") panic(err) } thread := this.threads[0] this.threads = this.threads[1:] this.cycles = this.cycles[1:] return thread } func (this *ThreadQ) Front(pos int) (*Thread, int64) { return this.threads[pos], this.cycles[pos] } func (this *ThreadQ) Remove(pos int) { this.threads = append(this.threads[:pos], this.threads[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *ThreadQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/logic/thread_scheduler.go ================================================ package logic import ( "errors" "fmt" "uPIMulator/src/misc" ) type ThreadScheduler struct { channel_id int rank_id int dpu_id int num_revolver_scheduling_cycles int64 threads []*Thread thread_q *ThreadQ stat_factory *misc.StatFactory } func (this *ThreadScheduler) Init( channel_id int, rank_id int, dpu_id int, threads []*Thread, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.num_revolver_scheduling_cycles = command_line_parser.IntParameter( "num_revolver_scheduling_cycles", ) this.threads = threads this.thread_q = new(ThreadQ) this.thread_q.Init(len(this.threads), 0) for _, thread := range threads { this.thread_q.Push(thread) } name := fmt.Sprintf("ThreadScheduler[%d_%d_%d]", channel_id, rank_id, dpu_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *ThreadScheduler) Fini() { for this.thread_q.CanPop(1) { this.thread_q.Pop() } this.thread_q.Fini() } func (this *ThreadScheduler) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *ThreadScheduler) NumIssuableThreads() int { num_issuable_threads := 0 for _, thread := range this.threads { if thread.ThreadState() == RUNNABLE { num_issuable_threads++ } } return num_issuable_threads } func (this *ThreadScheduler) Schedule() *Thread { var is_blocked bool is_blocked = false for i := 0; i < this.thread_q.Size(); i++ { thread := this.thread_q.Pop() this.thread_q.Push(thread) if thread.IssueCycle() >= this.num_revolver_scheduling_cycles { if thread.ThreadState() == RUNNABLE { thread.ResetIssueCycle() this.stat_factory.Increment("breakdown_run", 1) return thread } else if thread.ThreadState() == BLOCK { is_blocked = true } } } if is_blocked { this.stat_factory.Increment("breakdown_dma", 1) } else { this.stat_factory.Increment("breakdown_etc", 1) } return nil } func (this *ThreadScheduler) Boot(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == EMBRYO { thread.SetThreadState(RUNNABLE) return true } else if thread_state == ZOMBIE { thread.SetThreadState(RUNNABLE) return true } else { err := errors.New("thread is not bootable") panic(err) } } func (this *ThreadScheduler) Unboot() bool { for _, thread := range this.threads { thread_state := thread.ThreadState() if thread_state == ZOMBIE { thread.SetThreadState(EMBRYO) } else { err := errors.New("thread is not unbootable") panic(err) } } return true } func (this *ThreadScheduler) Sleep(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == RUNNABLE { thread.SetThreadState(SLEEP) return true } else { err := errors.New("thread is not sleepable") panic(err) } } func (this *ThreadScheduler) Block(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == RUNNABLE { thread.SetThreadState(BLOCK) return true } else { err := errors.New("thread is not blockable") panic(err) } } func (this *ThreadScheduler) Awake(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == EMBRYO { thread.SetThreadState(RUNNABLE) return true } else if thread_state == SLEEP { thread.SetThreadState(RUNNABLE) return true } else if thread_state == BLOCK { thread.SetThreadState(RUNNABLE) return true } else { err := errors.New("thread is not awakable") panic(err) } } func (this *ThreadScheduler) Shutdown(thread_id int) bool { thread := this.threads[thread_id] if thread.ThreadId() != thread_id { err := errors.New("thread's thread ID != thread ID") panic(err) } thread_state := thread.ThreadState() if thread_state == SLEEP { thread.SetThreadState(ZOMBIE) return true } else { err := errors.New("thread is not shotdownable") panic(err) } } func (this *ThreadScheduler) Cycle() { this.thread_q.Cycle() } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/condition_reg.go ================================================ package reg import ( "errors" "uPIMulator/src/device/linker/kernel/instruction/cc" ) type ConditionReg struct { conditions map[cc.Condition]bool } func (this *ConditionReg) Init() { this.conditions = make(map[cc.Condition]bool) this.ClearConditions() } func (this *ConditionReg) Fini() { } func (this *ConditionReg) Condition(condition cc.Condition) bool { if condition == cc.TRUE { return true } else if condition == cc.FALSE { return false } else { return this.conditions[condition] } } func (this *ConditionReg) SetCondition(condition cc.Condition) { if condition == cc.TRUE || condition == cc.FALSE { err := errors.New("condition is true or false") panic(err) } this.conditions[condition] = true } func (this *ConditionReg) ClearCondition(condition cc.Condition) { if condition == cc.TRUE || condition == cc.FALSE { err := errors.New("condition is true or false") panic(err) } this.conditions[condition] = false } func (this *ConditionReg) ClearConditions() { for i := 0; i <= int(cc.LARGE); i++ { condition := cc.Condition(i) if condition == cc.TRUE || condition == cc.FALSE { continue } else { this.conditions[condition] = false } } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/exception_reg.go ================================================ package reg import ( "uPIMulator/src/device/linker/kernel/instruction" ) type ExceptionReg struct { exceptions map[instruction.Exception]bool } func (this *ExceptionReg) Init() { this.exceptions = make(map[instruction.Exception]bool) this.ClearExceptions() } func (this *ExceptionReg) Fini() { } func (this *ExceptionReg) Exception(exception instruction.Exception) bool { return this.exceptions[exception] } func (this *ExceptionReg) SetException(exception instruction.Exception) { this.exceptions[exception] = true } func (this *ExceptionReg) ClearException(exception instruction.Exception) { this.exceptions[exception] = false } func (this *ExceptionReg) ClearExceptions() { for i := 0; i <= int(instruction.NOT_PROFILING); i++ { exception := instruction.Exception(i) this.exceptions[exception] = false } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/flag_reg.go ================================================ package reg import ( "uPIMulator/src/device/linker/kernel/instruction" ) type FlagReg struct { flags map[instruction.Flag]bool } func (this *FlagReg) Init() { this.flags = make(map[instruction.Flag]bool) this.ClearFlags() } func (this *FlagReg) Fini() { } func (this *FlagReg) Flag(flag instruction.Flag) bool { return this.flags[flag] } func (this *FlagReg) SetFlag(flag instruction.Flag) { this.flags[flag] = true } func (this *FlagReg) ClearFlag(flag instruction.Flag) { this.flags[flag] = false } func (this *FlagReg) ClearFlags() { for i := 0; i <= int(instruction.CARRY); i++ { flag := instruction.Flag(i) this.flags[flag] = false } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/gp_reg.go ================================================ package reg import ( "uPIMulator/src/device/abi" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type GpReg struct { gp_reg_descriptor *reg_descriptor.GpRegDescriptor word *abi.Word } func (this *GpReg) Init(index int) { this.gp_reg_descriptor = new(reg_descriptor.GpRegDescriptor) this.gp_reg_descriptor.Init(index) config_loader := new(misc.ConfigLoader) config_loader.Init() this.word = new(abi.Word) this.word.Init(config_loader.MramDataWidth()) } func (this *GpReg) Fini() { } func (this *GpReg) Index() int { return this.gp_reg_descriptor.Index() } func (this *GpReg) Read(representation abi.Representation) int64 { return this.word.Value(representation) } func (this *GpReg) Write(value int64) { this.word.SetValue(value) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/pc_reg.go ================================================ package reg import ( "uPIMulator/src/device/abi" "uPIMulator/src/misc" ) type PcReg struct { word *abi.Word } func (this *PcReg) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.word = new(abi.Word) this.word.Init(config_loader.AddressWidth()) } func (this *PcReg) Fini() { } func (this *PcReg) Read() int64 { return this.word.Value(abi.UNSIGNED) } func (this *PcReg) Write(value int64) { this.word.SetValue(value) } func (this *PcReg) Increment() { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) this.Write(this.Read() + iram_data_size) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/reg_file.go ================================================ package reg import ( "uPIMulator/src/device/abi" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/device/linker/kernel/instruction/cc" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type RegFile struct { gp_regs []*GpReg sp_reg *SpReg pc_reg *PcReg condition_reg *ConditionReg flag_reg *FlagReg exception_reg *ExceptionReg } func (this *RegFile) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.gp_regs = make([]*GpReg, 0) for i := 0; i < config_loader.NumGpRegisters(); i++ { gp_reg := new(GpReg) gp_reg.Init(i) this.gp_regs = append(this.gp_regs, gp_reg) } this.sp_reg = new(SpReg) this.sp_reg.Init(thread_id) this.pc_reg = new(PcReg) this.pc_reg.Init() this.condition_reg = new(ConditionReg) this.condition_reg.Init() this.flag_reg = new(FlagReg) this.flag_reg.Init() this.exception_reg = new(ExceptionReg) this.exception_reg.Init() } func (this *RegFile) Fini() { for _, gp_reg := range this.gp_regs { gp_reg.Fini() } this.sp_reg.Fini() this.pc_reg.Fini() this.condition_reg.Fini() this.flag_reg.Fini() this.exception_reg.Fini() } func (this *RegFile) ReadGpReg( gp_reg_descriptor *reg_descriptor.GpRegDescriptor, representation abi.Representation, ) int64 { return this.gp_regs[gp_reg_descriptor.Index()].Read(representation) } func (this *RegFile) ReadSpReg( sp_reg_descriptor *reg_descriptor.SpRegDescriptor, representation abi.Representation, ) int64 { return this.sp_reg.Read(sp_reg_descriptor, representation) } func (this *RegFile) ReadPairReg( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, representation abi.Representation, ) (int64, int64) { even := this.ReadGpReg(pair_reg_descriptor.EvenRegDescriptor(), representation) odd := this.ReadGpReg(pair_reg_descriptor.OddRegDescriptor(), abi.UNSIGNED) return even, odd } func (this *RegFile) ReadSrcReg( src_reg_descriptor *reg_descriptor.SrcRegDescriptor, representation abi.Representation, ) int64 { if src_reg_descriptor.IsGpRegDescriptor() { return this.ReadGpReg(src_reg_descriptor.GpRegDescriptor(), representation) } else { return this.ReadSpReg(src_reg_descriptor.SpRegDescriptor(), representation) } } func (this *RegFile) ReadPcReg() int64 { return this.pc_reg.Read() } func (this *RegFile) ReadConditionReg(condition cc.Condition) bool { return this.condition_reg.Condition(condition) } func (this *RegFile) ReadFlagReg(flag instruction.Flag) bool { return this.flag_reg.Flag(flag) } func (this *RegFile) ReadExceptionReg(exception instruction.Exception) bool { return this.exception_reg.Exception(exception) } func (this *RegFile) WriteGpReg(gp_reg_descriptor *reg_descriptor.GpRegDescriptor, value int64) { this.gp_regs[gp_reg_descriptor.Index()].Write(value) } func (this *RegFile) WritePairReg( pair_reg_descriptor *reg_descriptor.PairRegDescriptor, even int64, odd int64, ) { this.WriteGpReg(pair_reg_descriptor.EvenRegDescriptor(), even) this.WriteGpReg(pair_reg_descriptor.OddRegDescriptor(), odd) } func (this *RegFile) WritePcReg(value int64) { this.pc_reg.Write(value) } func (this *RegFile) IncrementPcReg() { this.pc_reg.Increment() } func (this *RegFile) SetCondition(condition cc.Condition) { this.condition_reg.SetCondition(condition) } func (this *RegFile) ClearCondition(condition cc.Condition) { this.condition_reg.ClearCondition(condition) } func (this *RegFile) ClearConditions() { this.condition_reg.ClearConditions() } func (this *RegFile) SetFlag(flag instruction.Flag) { this.flag_reg.SetFlag(flag) } func (this *RegFile) ClearFlag(flag instruction.Flag) { this.flag_reg.ClearFlag(flag) } func (this *RegFile) ClearFlags() { this.flag_reg.ClearFlags() } func (this *RegFile) SetException(exception instruction.Exception) { this.exception_reg.SetException(exception) } func (this *RegFile) ClearException(exception instruction.Exception) { this.exception_reg.ClearException(exception) } func (this *RegFile) ClearExceptions() { this.exception_reg.ClearExceptions() } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/reg/sp_reg.go ================================================ package reg import ( "errors" "uPIMulator/src/device/abi" "uPIMulator/src/device/linker/kernel/instruction/reg_descriptor" "uPIMulator/src/misc" ) type SpReg struct { zero *abi.Word one *abi.Word lneg *abi.Word mneg *abi.Word id *abi.Word id2 *abi.Word id4 *abi.Word id8 *abi.Word } func (this *SpReg) Init(thread_id int) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.zero = new(abi.Word) this.zero.Init(config_loader.MramDataWidth()) this.zero.SetValue(0) this.one = new(abi.Word) this.one.Init(config_loader.MramDataWidth()) this.one.SetValue(1) this.lneg = new(abi.Word) this.lneg.Init(config_loader.MramDataWidth()) this.lneg.SetValue(-1) this.mneg = new(abi.Word) this.mneg.Init(config_loader.MramDataWidth()) this.mneg.SetValue(int64(this.mneg.Width()) - 1) this.id = new(abi.Word) this.id.Init(config_loader.MramDataWidth()) this.id.SetValue(int64(thread_id)) this.id2 = new(abi.Word) this.id2.Init(config_loader.MramDataWidth()) this.id2.SetValue(int64(2 * thread_id)) this.id4 = new(abi.Word) this.id4.Init(config_loader.MramDataWidth()) this.id4.SetValue(int64(4 * thread_id)) this.id8 = new(abi.Word) this.id8.Init(config_loader.MramDataWidth()) this.id8.SetValue(int64(8 * thread_id)) } func (this *SpReg) Fini() { } func (this *SpReg) Read( sp_reg_descriptor *reg_descriptor.SpRegDescriptor, representation abi.Representation, ) int64 { if *sp_reg_descriptor == reg_descriptor.ZERO { return this.zero.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ONE { return this.one.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.LNEG { return this.lneg.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.MNEG { return this.mneg.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID { return this.id.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID2 { return this.id2.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID4 { return this.id4.Value(representation) } else if *sp_reg_descriptor == reg_descriptor.ID8 { return this.id8.Value(representation) } else { err := errors.New("sp reg descriptor is not valid") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/sram/atomic.go ================================================ package sram import ( "errors" "uPIMulator/src/misc" ) type Atomic struct { address int64 size int64 locks []*Lock } func (this *Atomic) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.AtomicOffset() this.size = config_loader.AtomicSize() this.locks = make([]*Lock, 0) for i := int64(0); i < this.size; i++ { lock := new(Lock) lock.Init() this.locks = append(this.locks, lock) } } func (this *Atomic) Fini() { for _, lock := range this.locks { lock.Fini() } } func (this *Atomic) Address() int64 { return this.address } func (this *Atomic) Size() int64 { return this.size } func (this *Atomic) CanAcquire(address int64) bool { return this.locks[this.Index(address)].CanAcquire() } func (this *Atomic) Acquire(address int64, thread_id int) { this.locks[this.Index(address)].Acquire(thread_id) } func (this *Atomic) CanRelease(address int64, thread_id int) bool { return this.locks[this.Index(address)].CanRelease(thread_id) } func (this *Atomic) Release(address int64, thread_id int) { this.locks[this.Index(address)].Release(thread_id) } func (this *Atomic) Index(address int64) int { if address < this.address { err := errors.New("address < atomic offset") panic(err) } else if address >= this.address+this.size { err := errors.New("address >= atomic offset + atomic size") panic(err) } return int(address - this.address) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/sram/iram.go ================================================ package sram import ( "errors" "uPIMulator/src/device/linker/kernel/instruction" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Iram struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Iram) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.IramOffset() this.size = config_loader.IramSize() this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < this.size; i++ { this.byte_stream.Append(0) } } func (this *Iram) Fini() { } func (this *Iram) Address() int64 { return this.address } func (this *Iram) Size() int64 { return this.size } func (this *Iram) Read(address int64) *instruction.Instruction { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < iram_data_size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } instruction_ := new(instruction.Instruction) instruction_.Decode(byte_stream) return instruction_ } func (this *Iram) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *Iram) Index(address int64) int { config_loader := new(misc.ConfigLoader) config_loader.Init() iram_data_size := int64(config_loader.IramDataWidth() / 8) if address < this.address { err := errors.New("address < IRAM offset") panic(err) } else if address+iram_data_size > this.address+this.size { err := errors.New("address >= IRAM offset + IRAM size") panic(err) } if (address-this.address)%iram_data_size != 0 { err := errors.New("addresses are not aligned with IRAM data size") panic(err) } return int(address - this.address) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/sram/lock.go ================================================ package sram import ( "errors" ) type Lock struct { thread_id *int } func (this *Lock) Init() { this.thread_id = nil } func (this *Lock) Fini() { if this.thread_id != nil { err := errors.New("thread ID != nil") panic(err) } } func (this *Lock) CanAcquire() bool { return this.thread_id == nil } func (this *Lock) Acquire(thread_id int) { if !this.CanAcquire() { err := errors.New("lock cannot be acquired") panic(err) } this.thread_id = new(int) *this.thread_id = thread_id } func (this *Lock) CanRelease(thread_id int) bool { return this.thread_id == nil || *this.thread_id == thread_id } func (this *Lock) Release(thread_id int) { if !this.CanRelease(thread_id) { err := errors.New("lock cannot be released") panic(err) } this.thread_id = nil } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/dpu/sram/wram.go ================================================ package sram import ( "errors" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Wram struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Wram) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = config_loader.WramOffset() this.size = config_loader.WramSize() this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < this.size; i++ { this.byte_stream.Append(0) } } func (this *Wram) Fini() { } func (this *Wram) Address() int64 { return this.address } func (this *Wram) Size() int64 { return this.size } func (this *Wram) Read(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } return byte_stream } func (this *Wram) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *Wram) Index(address int64) int { if address < this.address { err := errors.New("address < WRAM offset") panic(err) } else if address >= this.address+this.size { err := errors.New("address >= WRAM offset + WRAM size") panic(err) } return int(address - this.address) } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/rank/rank.go ================================================ package rank import ( "errors" "uPIMulator/src/device/simulator/dpu" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/misc" ) type Rank struct { channel_id int rank_id int dpus []*dpu.Dpu input_q *RankCommandQ ready_q *RankCommandQ scoreboard map[*dram.DmaCommand]*RankCommand } func (this *Rank) Init(channel_id int, rank_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpus = make([]*dpu.Dpu, 0) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) for i := 0; i < num_dpus_per_rank; i++ { dpu_ := new(dpu.Dpu) dpu_.Init(channel_id, rank_id, i, command_line_parser) this.dpus = append(this.dpus, dpu_) } this.input_q = new(RankCommandQ) this.input_q.Init(-1, 0) this.ready_q = new(RankCommandQ) this.ready_q.Init(-1, 0) this.scoreboard = make(map[*dram.DmaCommand]*RankCommand) } func (this *Rank) Fini() { for _, dpu_ := range this.dpus { dpu_.Fini() } this.input_q.Fini() this.ready_q.Fini() } func (this *Rank) ChannelId() int { return this.channel_id } func (this *Rank) RankId() int { return this.rank_id } func (this *Rank) NumDpus() int { return len(this.dpus) } func (this *Rank) Dpus() []*dpu.Dpu { return this.dpus } func (this *Rank) CanPush() bool { return this.input_q.CanPush(1) } func (this *Rank) Push(rank_command *RankCommand) { if !this.CanPush() { err := errors.New("rank cannot be pushed") panic(err) } this.input_q.Push(rank_command) } func (this *Rank) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Rank) Pop() *RankCommand { if !this.CanPop() { err := errors.New("rank cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Rank) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() this.input_q.Cycle() this.ready_q.Cycle() } func (this *Rank) ServiceInputQ() { if this.input_q.CanPop(1) { rank_command, _ := this.input_q.Front(0) dpu_id := rank_command.DpuId() if this.dpus[dpu_id].Dma().CanPush() { this.input_q.Pop() dma_command := rank_command.DmaCommand() this.dpus[dpu_id].Dma().Push(dma_command) this.scoreboard[dma_command] = rank_command } } } func (this *Rank) ServiceReadyQ() { for _, dpu_ := range this.dpus { if dpu_.Dma().CanPop() && this.ready_q.CanPush(1) { dma_command := dpu_.Dma().Pop() rank_command := this.scoreboard[dma_command] this.ready_q.Push(rank_command) delete(this.scoreboard, dma_command) } } } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/rank/rank_command.go ================================================ package rank import ( "errors" "uPIMulator/src/device/simulator/dpu/dram" ) type RankCommand struct { channel_id int rank_id int dpu_id int dma_command *dram.DmaCommand } func (this *RankCommand) Init( channel_id int, rank_id int, dpu_id int, dma_command *dram.DmaCommand, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if dpu_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.dma_command = dma_command } func (this *RankCommand) RankId() int { return this.rank_id } func (this *RankCommand) DpuId() int { return this.dpu_id } func (this *RankCommand) DmaCommand() *dram.DmaCommand { return this.dma_command } ================================================ FILE: golang_vm/uPIMulator/src/device/simulator/rank/rank_command_q.go ================================================ package rank import ( "errors" ) type RankCommandQ struct { size int timer int64 rank_commands []*RankCommand cycles []int64 } func (this *RankCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.rank_commands = make([]*RankCommand, 0) this.cycles = make([]int64, 0) } func (this *RankCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("rank command queue is not empty") panic(err) } } func (this *RankCommandQ) Size() int { return this.size } func (this *RankCommandQ) Length() int { return len(this.rank_commands) } func (this *RankCommandQ) Timer() int64 { return this.timer } func (this *RankCommandQ) IsEmpty() bool { return len(this.rank_commands) == 0 } func (this *RankCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.rank_commands) >= num_items } else { return true } } func (this *RankCommandQ) Push(rank_command *RankCommand) { if !this.CanPush(1) { err := errors.New("rank command queue cannot be pushed") panic(err) } this.rank_commands = append(this.rank_commands, rank_command) this.cycles = append(this.cycles, this.timer) } func (this *RankCommandQ) PushWithTimer(rank_command *RankCommand, timer int64) { if !this.CanPush(1) { err := errors.New("rank command queue cannot be pushed") panic(err) } this.rank_commands = append(this.rank_commands, rank_command) this.cycles = append(this.cycles, timer) } func (this *RankCommandQ) CanPop(num_items int) bool { if len(this.rank_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *RankCommandQ) Pop() *RankCommand { if !this.CanPop(1) { err := errors.New("rank command queue cannot be popped") panic(err) } rank_command := this.rank_commands[0] this.rank_commands = this.rank_commands[1:] this.cycles = this.cycles[1:] return rank_command } func (this *RankCommandQ) Front(pos int) (*RankCommand, int64) { return this.rank_commands[pos], this.cycles[pos] } func (this *RankCommandQ) Remove(pos int) { this.rank_commands = append(this.rank_commands[:pos], this.rank_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *RankCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/encoding/ascii_encoder.go ================================================ package encoding type AsciiEncoder struct { table map[string]uint8 inverted_table map[uint8]string unknown string } func (this *AsciiEncoder) Init() { this.table = make(map[string]uint8) this.inverted_table = make(map[uint8]string) this.table["\t"] = 9 this.table[" "] = 32 this.table["!"] = 33 this.table["\""] = 34 this.table["#"] = 35 this.table["$"] = 36 this.table["%"] = 37 this.table["&"] = 38 this.table["'"] = 39 this.table["("] = 40 this.table[")"] = 41 this.table["*"] = 42 this.table["+"] = 43 this.table[","] = 44 this.table["-"] = 45 this.table["."] = 46 this.table["/"] = 47 this.table["0"] = 48 this.table["1"] = 49 this.table["2"] = 50 this.table["3"] = 51 this.table["4"] = 52 this.table["5"] = 53 this.table["6"] = 54 this.table["7"] = 55 this.table["8"] = 56 this.table["9"] = 57 this.table[":"] = 58 this.table[""] = 59 this.table["<"] = 60 this.table["="] = 61 this.table[">"] = 62 this.table["?"] = 63 this.table["@"] = 64 this.table["A"] = 65 this.table["B"] = 66 this.table["C"] = 67 this.table["D"] = 68 this.table["E"] = 69 this.table["F"] = 70 this.table["G"] = 71 this.table["H"] = 72 this.table["I"] = 73 this.table["J"] = 74 this.table["K"] = 75 this.table["L"] = 76 this.table["M"] = 77 this.table["N"] = 78 this.table["O"] = 79 this.table["P"] = 80 this.table["Q"] = 81 this.table["R"] = 82 this.table["S"] = 83 this.table["T"] = 84 this.table["U"] = 85 this.table["V"] = 86 this.table["W"] = 87 this.table["X"] = 88 this.table["Y"] = 89 this.table["Z"] = 90 this.table["["] = 91 this.table["\\"] = 92 this.table["]"] = 93 this.table["^"] = 94 this.table["_"] = 95 this.table["`"] = 96 this.table["a"] = 97 this.table["b"] = 98 this.table["c"] = 99 this.table["d"] = 100 this.table["e"] = 101 this.table["f"] = 102 this.table["g"] = 103 this.table["h"] = 104 this.table["i"] = 105 this.table["j"] = 106 this.table["k"] = 107 this.table["l"] = 108 this.table["m"] = 109 this.table["n"] = 110 this.table["o"] = 111 this.table["p"] = 112 this.table["q"] = 113 this.table["r"] = 114 this.table["s"] = 115 this.table["t"] = 116 this.table["u"] = 117 this.table["v"] = 118 this.table["w"] = 119 this.table["x"] = 120 this.table["y"] = 121 this.table["z"] = 122 this.table["{"] = 123 this.table["|"] = 124 this.table["}"] = 125 this.table["~"] = 126 this.table["Ç"] = 128 this.table["ü"] = 129 this.table["é"] = 130 this.table["â"] = 131 this.table["ä"] = 132 this.table["à"] = 133 this.table["å"] = 134 this.table["ç"] = 135 this.table["ê"] = 136 this.table["ë"] = 137 this.table["è"] = 138 this.table["ï"] = 139 this.table["î"] = 140 this.table["ì"] = 141 this.table["Ä"] = 142 this.table["Å"] = 143 this.table["É"] = 144 this.table["æ"] = 145 this.table["Æ"] = 146 this.table["ô"] = 147 this.table["ö"] = 148 this.table["ò"] = 149 this.table["û"] = 150 this.table["ù"] = 151 this.table["ÿ"] = 152 this.table["Ö"] = 153 this.table["Ü"] = 154 this.table["ø"] = 155 this.table["£"] = 156 this.table["Ø"] = 157 this.table["×"] = 158 this.table["ƒ"] = 159 this.table["á"] = 160 this.table["í"] = 161 this.table["ó"] = 162 this.table["ú"] = 163 this.table["ñ"] = 164 this.table["Ñ"] = 165 this.table["ª"] = 166 this.table["º"] = 167 this.table["¿"] = 168 this.table["®"] = 169 this.table["¬"] = 170 this.table["½"] = 171 this.table["¼"] = 172 this.table["¡"] = 173 this.table["«"] = 174 this.table["»"] = 175 this.table["░"] = 176 this.table["▒"] = 177 this.table["▓"] = 178 this.table["│"] = 179 this.table["┤"] = 180 this.table["Á"] = 181 this.table["Â"] = 182 this.table["À"] = 183 this.table["©"] = 184 this.table["╣"] = 185 this.table["║"] = 186 this.table["╗"] = 187 this.table["╝"] = 188 this.table["¢"] = 189 this.table["¥"] = 190 this.table["┐"] = 191 this.table["└"] = 192 this.table["┴"] = 193 this.table["┬"] = 194 this.table["├"] = 195 this.table["─"] = 196 this.table["┼"] = 197 this.table["ã"] = 198 this.table["Ã"] = 199 this.table["╚"] = 200 this.table["╔"] = 201 this.table["╩"] = 202 this.table["╦"] = 203 this.table["╠"] = 204 this.table["═"] = 205 this.table["╬"] = 206 this.table["¤"] = 207 this.table["ð"] = 208 this.table["Ð"] = 209 this.table["Ê"] = 210 this.table["Ë"] = 211 this.table["È"] = 212 this.table["ı"] = 213 this.table["Í"] = 214 this.table["Î"] = 215 this.table["Ï"] = 216 this.table["┘"] = 217 this.table["┌"] = 218 this.table["█"] = 219 this.table["▄"] = 220 this.table["¦"] = 221 this.table["Ì"] = 222 this.table["▀"] = 223 this.table["Ó"] = 224 this.table["ß"] = 225 this.table["Ô"] = 226 this.table["Ò"] = 227 this.table["õ"] = 228 this.table["Õ"] = 229 this.table["µ"] = 230 this.table["þ"] = 231 this.table["Þ"] = 232 this.table["Ú"] = 233 this.table["Û"] = 234 this.table["Ù"] = 235 this.table["ý"] = 236 this.table["Ý"] = 237 this.table["¯"] = 238 this.table["´"] = 239 this.table["≡"] = 240 this.table["±"] = 241 this.table["‗"] = 242 this.table["¾"] = 243 this.table["¶"] = 244 this.table["§"] = 245 this.table["÷"] = 246 this.table["¸"] = 247 this.table["°"] = 248 this.table["¨"] = 249 this.table["·"] = 250 this.table["¹"] = 251 this.table["³"] = 252 this.table["²"] = 253 this.table["■"] = 254 for character, value := range this.table { this.inverted_table[value] = character } this.unknown = "■" } func (this *AsciiEncoder) Encode(characters string) *ByteStream { byte_stream := new(ByteStream) byte_stream.Init() for _, character := range characters { value := this.table[string(character)] byte_stream.Append(value) } return byte_stream } func (this *AsciiEncoder) Decode(byte_stream *ByteStream) string { characters := "" for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) characters += this.inverted_table[value] } return characters } func (this *AsciiEncoder) Unknown() string { return this.unknown } ================================================ FILE: golang_vm/uPIMulator/src/encoding/byte_stream.go ================================================ package encoding import ( "errors" ) type ByteStream struct { bytes []uint8 } func (this *ByteStream) Init() { this.bytes = make([]uint8, 0) } func (this *ByteStream) Size() int64 { return int64(len(this.bytes)) } func (this *ByteStream) Get(pos int) uint8 { return this.bytes[pos] } func (this *ByteStream) Set(pos int, value uint8) { this.bytes[pos] = value } func (this *ByteStream) Append(value uint8) { this.bytes = append(this.bytes, value) } func (this *ByteStream) Remove(pos int) { this.bytes = append(this.bytes[:pos], this.bytes[pos+1:]...) } func (this *ByteStream) Merge(byte_stream *ByteStream) { for i := int64(0); i < byte_stream.Size(); i++ { value := byte_stream.Get(int(i)) this.Append(value) } } func (this *ByteStream) Signbit() bool { last_byte := this.Get(int(this.Size() - 1)) sign_bit := ((int(last_byte) & (1 << 7)) >> 7) == 1 return sign_bit } func (this *ByteStream) SignedValue() int64 { if this.Size() > 8 { err := errors.New("byte stream cannot convert into an integer") panic(err) } value := int64(0) for i := int64(0); i < this.Size()-1; i++ { value += int64(this.Get(int(i))) * this.Pow2(int(8*i)) } last_byte := this.Get(int(this.Size() - 1)) for i := 0; i < 7; i++ { bit := ((int(last_byte) & (1 << i)) >> i) == 1 if bit { value += this.Pow2(8*(len(this.bytes)-1) + i) } } if this.Signbit() { value -= this.Pow2(8*len(this.bytes) - 1) } return value } func (this *ByteStream) UnsignedValue() int64 { if this.Size() > 8 { err := errors.New("byte stream cannot convert into an integer") panic(err) } value := int64(0) for i := int64(0); i < this.Size(); i++ { value += int64(this.Get(int(i))) * this.Pow2(int(8*i)) } return value } func (this *ByteStream) Pow2(exponent int) int64 { value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } ================================================ FILE: golang_vm/uPIMulator/src/host/abi/binary.go ================================================ package abi import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser" "uPIMulator/src/misc" ) type Binary struct { benchmark string num_dpus int num_tasklets int token_stream *lexer.TokenStream ast *parser.Ast relocatable *Relocatable } func (this *Binary) Init(benchmark string, num_dpus int, num_tasklets int) { if num_dpus <= 0 { err := errors.New("num DPUs <= 0") panic(err) } else if num_tasklets <= 0 { err := errors.New("num tasklets <= 0") panic(err) } this.benchmark = benchmark this.num_dpus = num_dpus this.num_tasklets = num_tasklets this.token_stream = nil this.ast = nil this.relocatable = nil } func (this *Binary) Benchmark() string { return this.benchmark } func (this *Binary) NumDpus() int { return this.num_dpus } func (this *Binary) NumTasklets() int { return this.num_tasklets } func (this *Binary) TokenStream() *lexer.TokenStream { if this.token_stream == nil { err := errors.New("token stream == nil") panic(err) } return this.token_stream } func (this *Binary) SetTokenStream(token_stream *lexer.TokenStream) { if this.token_stream != nil { err := errors.New("token stream != nil") panic(err) } this.token_stream = token_stream } func (this *Binary) Ast() *parser.Ast { if this.ast == nil { err := errors.New("AST == nil") panic(err) } return this.ast } func (this *Binary) SetAst(ast *parser.Ast) { if this.ast != nil { err := errors.New("AST != nil") panic(err) } this.ast = ast } func (this *Binary) Relocatable() *Relocatable { if this.relocatable == nil { err := errors.New("relocatable == nil") panic(err) } return this.relocatable } func (this *Binary) SetRelocatable(relocatable *Relocatable) { if this.relocatable != nil { err := errors.New("relocatable != nil") panic(err) } this.relocatable = relocatable } func (this *Binary) Dump(path string) { lines := make([]string, 0) for _, label := range this.relocatable.Labels() { lines = append(lines, label.Stringify()) } file_dumper := new(misc.FileDumper) file_dumper.Init(path) file_dumper.WriteLines(lines) } ================================================ FILE: golang_vm/uPIMulator/src/host/abi/bytecode.go ================================================ package abi import ( "errors" "fmt" ) type Bytecode struct { op_code OpCode arg1 *int64 arg2 *int64 str1 *string str2 *string } func (this *Bytecode) Init(op_code OpCode, args []int64, strs []string) { this.op_code = op_code if len(args) == 0 { this.arg1 = nil this.arg2 = nil } else if len(args) == 1 { this.arg1 = new(int64) *this.arg1 = args[0] this.arg2 = nil } else if len(args) == 2 { this.arg1 = new(int64) *this.arg1 = args[0] this.arg2 = new(int64) *this.arg2 = args[1] } else { err := errors.New("len(args) > 2") panic(err) } if len(strs) == 0 { this.str1 = nil this.str2 = nil } else if len(strs) == 1 { this.str1 = new(string) *this.str1 = strs[0] this.str2 = nil } else if len(strs) == 2 { this.str1 = new(string) *this.str1 = strs[0] this.str2 = new(string) *this.str2 = strs[1] } else { err := errors.New("len(strs) > 2") panic(err) } } func (this *Bytecode) OpCode() OpCode { return this.op_code } func (this *Bytecode) Arg1() int64 { if this.arg1 == nil { err := errors.New("arg1 == nil") panic(err) } return *this.arg1 } func (this *Bytecode) Arg2() int64 { if this.arg2 == nil { err := errors.New("arg2 == nil") panic(err) } return *this.arg2 } func (this *Bytecode) Str1() string { if this.str1 == nil { err := errors.New("str1 == nil") panic(err) } return *this.str1 } func (this *Bytecode) Str2() string { if this.str2 == nil { err := errors.New("str2 == nil") panic(err) } return *this.str2 } func (this *Bytecode) Stringify() string { if this.op_code == NEW_SCOPE { return "NEW_SCOPE" } else if this.op_code == DELETE_SCOPE { return "DELETE_SCOPE" } else if this.op_code == PUSH_CHAR { return fmt.Sprintf("PUSH_CHAR %d", *this.arg1) } else if this.op_code == PUSH_SHORT { return fmt.Sprintf("PUSH_SHORT %d", *this.arg1) } else if this.op_code == PUSH_INT { return fmt.Sprintf("PUSH_INT %d", *this.arg1) } else if this.op_code == PUSH_LONG { return fmt.Sprintf("PUSH_LONG %d", *this.arg1) } else if this.op_code == PUSH_STRING { return fmt.Sprintf("PUSH_STRING %s", *this.str1) } else if this.op_code == POP { return "POP" } else if this.op_code == BEGIN_STRUCT { return fmt.Sprintf("BEGIN_STRUCT %s", *this.str1) } else if this.op_code == APPEND_VOID { return fmt.Sprintf("APPEND_VOID %d %s", *this.arg1, *this.str1) } else if this.op_code == APPEND_CHAR { return fmt.Sprintf("APPEND_VOID %d %s", *this.arg1, *this.str1) } else if this.op_code == APPEND_SHORT { return fmt.Sprintf("APPEND_SHORT %d %s", *this.arg1, *this.str1) } else if this.op_code == APPEND_INT { return fmt.Sprintf("APPEND_INT %d %s", *this.arg1, *this.str1) } else if this.op_code == APPEND_LONG { return fmt.Sprintf("APPEND_LONG %d %s", *this.arg1, *this.str1) } else if this.op_code == APPEND_STRUCT { return fmt.Sprintf("APPEND_STRUCT %d %s %s", *this.arg1, *this.str1, *this.str2) } else if this.op_code == END_STRUCT { return "END_STRUCT" } else if this.op_code == NEW_GLOBAL_VOID { return fmt.Sprintf("NEW_GLOBAL_VOID %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_GLOBAL_CHAR { return fmt.Sprintf("NEW_GLOBAL_CHAR %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_GLOBAL_SHORT { return fmt.Sprintf("NEW_GLOBAL_SHORT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_GLOBAL_INT { return fmt.Sprintf("NEW_GLOBAL_INT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_GLOBAL_LONG { return fmt.Sprintf("NEW_GLOBAL_LONG %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_VOID { return fmt.Sprintf("NEW_FAST_VOID %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_CHAR { return fmt.Sprintf("NEW_FAST_CHAR %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_SHORT { return fmt.Sprintf("NEW_FAST_SHORT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_INT { return fmt.Sprintf("NEW_FAST_INT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_LONG { return fmt.Sprintf("NEW_FAST_LONG %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_FAST_STRUCT { return fmt.Sprintf("NEW_FAST_STRUCT %d %s %s", *this.arg1, *this.str1, *this.str2) } else if this.op_code == NEW_ARG_VOID { return fmt.Sprintf("NEW_ARG_VOID %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_ARG_CHAR { return fmt.Sprintf("NEW_ARG_CHAR %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_ARG_SHORT { return fmt.Sprintf("NEW_ARG_SHORT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_ARG_INT { return fmt.Sprintf("NEW_ARG_INT %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_ARG_LONG { return fmt.Sprintf("NEW_ARG_LONG %d %s", *this.arg1, *this.str1) } else if this.op_code == NEW_ARG_STRUCT { return fmt.Sprintf("NEW_ARG_STRUCT %d %s %s", *this.arg1, *this.str1, *this.str2) } else if this.op_code == NEW_RETURN_VOID { return fmt.Sprintf("NEW_RETURN_VOID %d", *this.arg1) } else if this.op_code == NEW_RETURN_CHAR { return fmt.Sprintf("NEW_RETURN_CHAR %d", *this.arg1) } else if this.op_code == NEW_RETURN_SHORT { return fmt.Sprintf("NEW_RETURN_SHORT %d", *this.arg1) } else if this.op_code == NEW_RETURN_INT { return fmt.Sprintf("NEW_RETURN_INT %d", *this.arg1) } else if this.op_code == NEW_RETURN_LONG { return fmt.Sprintf("NEW_RETURN_LONG %d", *this.arg1) } else if this.op_code == NEW_RETURN_STRUCT { return fmt.Sprintf("NEW_RETURN_STRUCT %d %s", *this.arg1, *this.str1) } else if this.op_code == SIZEOF_VOID { return fmt.Sprintf("SIZEOF_VOID %d", *this.arg1) } else if this.op_code == SIZEOF_CHAR { return fmt.Sprintf("SIZEOF_CHAR %d", *this.arg1) } else if this.op_code == SIZEOF_SHORT { return fmt.Sprintf("SIZEOF_SHORT %d", *this.arg1) } else if this.op_code == SIZEOF_INT { return fmt.Sprintf("SIZEOF_INT %d", *this.arg1) } else if this.op_code == SIZEOF_LONG { return fmt.Sprintf("SIZEOF_LONG %d", *this.arg1) } else if this.op_code == SIZEOF_STRUCT { return fmt.Sprintf("SIZEOF_STRUCT %d %s", *this.arg1, *this.str1) } else if this.op_code == GET_IDENTIFIER { return fmt.Sprintf("GET_IDENTIFIER %s", *this.str1) } else if this.op_code == GET_ARG_IDENTIFIER { return fmt.Sprintf("GET_ARG_IDENTIFIER %s", *this.str1) } else if this.op_code == GET_SUBSCRIPT { return "GET_SUBSCRIPT" } else if this.op_code == GET_ACCESS { return fmt.Sprintf("GET_ACCESS %s", *this.str1) } else if this.op_code == GET_REFERENCE { return fmt.Sprintf("GET_REFERENCE %s", *this.str1) } else if this.op_code == GET_ADDRESS { return "GET_ADDRESS" } else if this.op_code == GET_VALUE { return "GET_VALUE" } else if this.op_code == ALLOC { return "ALLOC" } else if this.op_code == FREE { return "FREE" } else if this.op_code == ASSERT { return "ASSERT" } else if this.op_code == ADD { return "ADD" } else if this.op_code == SUB { return "SUB" } else if this.op_code == MUL { return "MUL" } else if this.op_code == DIV { return "DIV" } else if this.op_code == MOD { return "MOD" } else if this.op_code == LSHIFT { return "LSHIFT" } else if this.op_code == RSHIFT { return "RSHIFT" } else if this.op_code == NEGATE { return "NEGATE" } else if this.op_code == TILDE { return "TILDE" } else if this.op_code == SQRT { return "SQRT" } else if this.op_code == BITWISE_AND { return "BITWISE_AND" } else if this.op_code == BITWISE_XOR { return "BITWISE_XOR" } else if this.op_code == BITWISE_OR { return "BITWISE_OR" } else if this.op_code == LOGICAL_AND { return "LOGICAL_AND" } else if this.op_code == LOGICAL_OR { return "LOGICAL_OR" } else if this.op_code == LOGICAL_NOT { return "LOGICAL_NOT" } else if this.op_code == EQ { return "EQ" } else if this.op_code == NOT_EQ { return "NOT_EQ" } else if this.op_code == LESS { return "LESS" } else if this.op_code == LESS_EQ { return "LESS_EQ" } else if this.op_code == GREATER { return "GREATER" } else if this.op_code == GREATER_EQ { return "GREATER_EQ" } else if this.op_code == CONDITIONAL { return "CONDITIONAL" } else if this.op_code == ASSIGN { return "ASSIGN" } else if this.op_code == ASSIGN_STAR { return "ASSIGN_STAR" } else if this.op_code == ASSIGN_DIV { return "ASSIGN_DIV" } else if this.op_code == ASSIGN_MOD { return "ASSIGN_MOD" } else if this.op_code == ASSIGN_ADD { return "ASSIGN_ADD" } else if this.op_code == ASSIGN_SUB { return "ASSIGN_SUB" } else if this.op_code == ASSIGN_LSHIFT { return "ASSIGN_LSHIFT" } else if this.op_code == ASSIGN_RSHIFT { return "ASSIGN_RSHIFT" } else if this.op_code == ASSIGN_BITWISE_AND { return "ASSIGN_BITWISE_AND" } else if this.op_code == ASSIGN_BITWISE_XOR { return "ASSIGN_BITWISE_XOR" } else if this.op_code == ASSIGN_BITWISE_OR { return "ASSIGN_BITWISE_OR" } else if this.op_code == ASSIGN_PLUS_PLUS { return "ASSIGN_PLUS_PLUS" } else if this.op_code == ASSIGN_MINUS_MINUS { return "ASSIGN_MINUS_MINUS" } else if this.op_code == ASSIGN_RETURN { return "ASSIGN_RETURN" } else if this.op_code == JUMP { return fmt.Sprintf("JUMP %s", *this.str1) } else if this.op_code == JUMP_IF_ZERO { return fmt.Sprintf("JUMP_IF_ZERO %s", *this.str1) } else if this.op_code == JUMP_IF_NONZERO { return fmt.Sprintf("JUMP_IF_NONZERO %s", *this.str1) } else if this.op_code == CALL { return fmt.Sprintf("CALL %s", *this.str1) } else if this.op_code == RETURN { return "RETURN" } else if this.op_code == NOP { return "NOP" } else if this.op_code == DPU_ALLOC { return fmt.Sprintf("DPU_ALLOC %d", *this.arg1) } else if this.op_code == DPU_LOAD { return fmt.Sprintf("DPU_LOAD %d %s", *this.arg1, *this.str1) } else if this.op_code == DPU_PREPARE { return "DPU_PREPARE" } else if this.op_code == DPU_TRANSFER { return "DPU_TRANSFER" } else if this.op_code == DPU_COPY_TO { return "DPU_COPY_TO" } else if this.op_code == DPU_COPY_FROM { return "DPU_COPY_FROM" } else if this.op_code == DPU_LAUNCH { return "DPU_LAUNCH" } else if this.op_code == DPU_FREE { return "DPU_FREE" } else { err := errors.New("op code is not valid") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/host/abi/label.go ================================================ package abi import ( "fmt" ) type Label struct { name string bytecodes []*Bytecode } func (this *Label) Init(name string) { this.name = name } func (this *Label) Name() string { return this.name } func (this *Label) Length() int { return len(this.bytecodes) } func (this *Label) Get(index int) *Bytecode { return this.bytecodes[index] } func (this *Label) Append(bytecode *Bytecode) { this.bytecodes = append(this.bytecodes, bytecode) } func (this *Label) Stringify() string { ss := fmt.Sprintf("%s:\n", this.name) for i := 0; i < len(this.bytecodes); i++ { bytecode := this.bytecodes[i] if i != len(this.bytecodes)-1 { ss += fmt.Sprintf("\t%s\n", bytecode.Stringify()) } else { ss += fmt.Sprintf("\t%s", bytecode.Stringify()) } } return ss } ================================================ FILE: golang_vm/uPIMulator/src/host/abi/op_code.go ================================================ package abi type OpCode int const ( NEW_SCOPE OpCode = iota DELETE_SCOPE PUSH_CHAR PUSH_SHORT PUSH_INT PUSH_LONG PUSH_STRING POP BEGIN_STRUCT APPEND_VOID APPEND_CHAR APPEND_SHORT APPEND_INT APPEND_LONG APPEND_STRUCT END_STRUCT NEW_GLOBAL_VOID NEW_GLOBAL_CHAR NEW_GLOBAL_SHORT NEW_GLOBAL_INT NEW_GLOBAL_LONG NEW_FAST_VOID NEW_FAST_CHAR NEW_FAST_SHORT NEW_FAST_INT NEW_FAST_LONG NEW_FAST_STRUCT NEW_ARG_VOID NEW_ARG_CHAR NEW_ARG_SHORT NEW_ARG_INT NEW_ARG_LONG NEW_ARG_STRUCT NEW_RETURN_VOID NEW_RETURN_CHAR NEW_RETURN_SHORT NEW_RETURN_INT NEW_RETURN_LONG NEW_RETURN_STRUCT SIZEOF_VOID SIZEOF_CHAR SIZEOF_SHORT SIZEOF_INT SIZEOF_LONG SIZEOF_STRUCT GET_IDENTIFIER GET_ARG_IDENTIFIER GET_SUBSCRIPT GET_ACCESS GET_REFERENCE GET_ADDRESS GET_VALUE ALLOC FREE ASSERT ADD SUB MUL DIV MOD LSHIFT RSHIFT NEGATE TILDE SQRT BITWISE_AND BITWISE_XOR BITWISE_OR LOGICAL_AND LOGICAL_OR LOGICAL_NOT EQ NOT_EQ LESS LESS_EQ GREATER GREATER_EQ CONDITIONAL ASSIGN ASSIGN_STAR ASSIGN_DIV ASSIGN_MOD ASSIGN_ADD ASSIGN_SUB ASSIGN_LSHIFT ASSIGN_RSHIFT ASSIGN_BITWISE_AND ASSIGN_BITWISE_XOR ASSIGN_BITWISE_OR ASSIGN_PLUS_PLUS ASSIGN_MINUS_MINUS ASSIGN_RETURN JUMP JUMP_IF_ZERO JUMP_IF_NONZERO CALL RETURN NOP DPU_ALLOC DPU_LOAD DPU_PREPARE DPU_TRANSFER DPU_COPY_TO DPU_COPY_FROM DPU_LAUNCH DPU_FREE ) ================================================ FILE: golang_vm/uPIMulator/src/host/abi/relocatable.go ================================================ package abi import ( "errors" "fmt" ) type Relocatable struct { labels []*Label cur_func *Label cur_loop_condition *Label cur_loop_body *Label cur_loop_end *Label cur_label *Label label_brk int } func (this *Relocatable) Init() { this.labels = make([]*Label, 0) this.cur_func = nil this.cur_loop_condition = nil this.cur_loop_body = nil this.cur_loop_end = nil this.cur_label = nil this.label_brk = 0 } func (this *Relocatable) HasFunc(func_name string) bool { return this.HasLabel(func_name) } func (this *Relocatable) CurFunc() *Label { if this.cur_func == nil { err := errors.New("cur func == nil") panic(err) } return this.cur_func } func (this *Relocatable) NewFunc(func_name string) *Label { label := this.NewNamedLabel(func_name) return label } func (this *Relocatable) SwitchFunc(func_name string) { this.cur_func = this.Label(func_name) } func (this *Relocatable) CurLoopCondition() *Label { if this.cur_loop_condition == nil { err := errors.New("cur loop condition == nil") panic(err) } return this.cur_loop_condition } func (this *Relocatable) CurLoopBody() *Label { if this.cur_loop_body == nil { err := errors.New("cur loop body == nil") panic(err) } return this.cur_loop_body } func (this *Relocatable) CurLoopEnd() *Label { if this.cur_loop_end == nil { err := errors.New("cur loop end == nil") panic(err) } return this.cur_loop_end } func (this *Relocatable) NewLoop() (*Label, *Label, *Label) { this.cur_loop_condition = this.NewUnnamedLabel() this.cur_loop_body = this.NewUnnamedLabel() this.cur_loop_end = this.NewUnnamedLabel() return this.cur_loop_condition, this.cur_loop_body, this.cur_loop_end } func (this *Relocatable) HasLabel(label_name string) bool { for _, label := range this.labels { if label.Name() == label_name { return true } } return false } func (this *Relocatable) Label(label_name string) *Label { if !this.HasLabel(label_name) { err_msg := fmt.Sprintf("label (%s) is not found", label_name) err := errors.New(err_msg) panic(err) } for _, label := range this.labels { if label.Name() == label_name { return label } } return nil } func (this *Relocatable) Labels() []*Label { return this.labels } func (this *Relocatable) NewNamedLabel(label_name string) *Label { if this.HasLabel(label_name) { err_msg := fmt.Sprintf("label (%s) already exists", label_name) err := errors.New(err_msg) panic(err) } label := new(Label) label.Init(label_name) this.labels = append(this.labels, label) return label } func (this *Relocatable) NewUnnamedLabel() *Label { label_name := fmt.Sprintf("L%d", this.label_brk) this.label_brk++ label := new(Label) label.Init(label_name) this.labels = append(this.labels, label) return label } func (this *Relocatable) SwitchLabel(label_name string) { this.cur_label = this.Label(label_name) } func (this *Relocatable) CurLabel() *Label { return this.cur_label } func (this *Relocatable) NewBytecode(op_code OpCode, args []int64, strs []string) { bytecode := new(Bytecode) bytecode.Init(op_code, args, strs) this.cur_label.Append(bytecode) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/codegen/codegen.go ================================================ package codegen import ( "errors" "strconv" "uPIMulator/src/host/abi" "uPIMulator/src/host/interpreter/codegen/type_system" "uPIMulator/src/host/interpreter/parser" "uPIMulator/src/host/interpreter/parser/decl" "uPIMulator/src/host/interpreter/parser/directive" "uPIMulator/src/host/interpreter/parser/expr" "uPIMulator/src/host/interpreter/parser/stmt" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type Codegen struct { benchmark string num_dpus int num_tasklets int data_prep_params int dpu_mram_heap_pointer_name int64 type_system *type_system.TypeSystem relocatable *abi.Relocatable cur_block_depth int block_depths map[string]int } func (this *Codegen) Init( benchmark string, num_dpus int, num_tasklets int, data_prep_params int, dpu_mram_heap_pointer_name int64, ) { this.benchmark = benchmark this.num_dpus = num_dpus this.num_tasklets = num_tasklets this.data_prep_params = data_prep_params this.dpu_mram_heap_pointer_name = dpu_mram_heap_pointer_name this.type_system = new(type_system.TypeSystem) this.type_system.Init() this.relocatable = new(abi.Relocatable) this.relocatable.Init() this.cur_block_depth = 0 this.block_depths = make(map[string]int) } func (this *Codegen) Codegen(ast *parser.Ast) *abi.Relocatable { this.CodegenInitBootstrap() for i := 0; i < ast.Length(); i++ { stack_item := ast.Get(i) if stack_item.StackItemType() == parser.DIRECTIVE { this.CodegenDirective(stack_item.Directive()) } else if stack_item.StackItemType() == parser.DECL { this.CodegenDecl(stack_item.Decl()) } else { err := errors.New("stack item is not directive nor decl") panic(err) } } this.CodegenFiniBootstrap() return this.relocatable } func (this *Codegen) CodegenInitBootstrap() { this.relocatable.NewFunc("__bootstrap") this.relocatable.SwitchLabel("__bootstrap") this.relocatable.NewBytecode(abi.NEW_SCOPE, []int64{}, []string{}) this.relocatable.NewBytecode(abi.BEGIN_STRUCT, []int64{}, []string{"dpu_set_t"}) this.relocatable.NewBytecode(abi.APPEND_INT, []int64{0}, []string{"foo"}) this.relocatable.NewBytecode(abi.END_STRUCT, []int64{}, []string{}) } func (this *Codegen) CodegenFiniBootstrap() { this.relocatable.SwitchLabel("__bootstrap") this.relocatable.NewBytecode(abi.CALL, []int64{}, []string{"main"}) this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) } func (this *Codegen) CodegenDirective(directive_ *directive.Directive) { if directive_.DirectiveType() == directive.INCLUDE { this.CodegenIncludeDirective(directive_.IncludeDirective()) } else if directive_.DirectiveType() == directive.DEFINE { this.CodegenDefineDirective(directive_.DefineDirective()) } else { err := errors.New("directive type is not valid") panic(err) } } func (this *Codegen) CodegenIncludeDirective(include_directive *directive.IncludeDirective) { } func (this *Codegen) CodegenDefineDirective(define_directive *directive.DefineDirective) { this.relocatable.SwitchLabel("__bootstrap") lvalue := define_directive.Lvalue() rvalue := define_directive.Rvalue() if rvalue.ExprType() == expr.PRIMARY { if rvalue.PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER { err := errors.New("rvalue primary expr type is identifier") panic(err) } else if rvalue.PrimaryExpr().PrimaryExprType() == expr.NUMBER { if lvalue.Attribute() == "NUM_DPUS" { this.relocatable.NewBytecode(abi.NEW_GLOBAL_INT, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{int64(this.num_dpus)}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } else if lvalue.Attribute() == "NUM_TASKLETS" { this.relocatable.NewBytecode(abi.NEW_GLOBAL_INT, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{int64(this.num_tasklets)}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } else if lvalue.Attribute() == "DATA_PREP_PARAMS" { this.relocatable.NewBytecode(abi.NEW_GLOBAL_INT, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{int64(this.data_prep_params)}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } else { rvalue_value, err := strconv.ParseInt(rvalue.PrimaryExpr().Token().Attribute(), 10, 64) if err != nil { panic(err) } this.relocatable.NewBytecode(abi.NEW_GLOBAL_INT, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{0}, []string{lvalue.Attribute()}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{rvalue_value}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } } else if rvalue.PrimaryExpr().PrimaryExprType() == expr.STRING { } else if rvalue.PrimaryExpr().PrimaryExprType() == expr.NULLPTR { err := errors.New("rvalue primary expr type is nullptr") panic(err) } else if rvalue.PrimaryExpr().PrimaryExprType() == expr.PAREN { err := errors.New("rvalue primary expr type is paren") panic(err) } else { err := errors.New("primary expr type is valid") panic(err) } } else { err := errors.New("rvalue expr type is primary") panic(err) } } func (this *Codegen) CodegenDecl(decl_ *decl.Decl) { if decl_.DeclType() == decl.STRUCT_DEF { this.CodegenStructDef(decl_.StructDef()) } else if decl_.DeclType() == decl.FUNC_DECL { this.CodegenFuncDecl(decl_.FuncDecl()) } else if decl_.DeclType() == decl.FUNC_DEF { this.CodegenFuncDef(decl_.FuncDef()) } else { err := errors.New("decl type is not valid") panic(err) } } func (this *Codegen) CodegenStructDef(struct_def *decl.StructDef) { this.relocatable.SwitchLabel("__bootstrap") struct_name := struct_def.Identifier().Attribute() this.relocatable.NewBytecode(abi.BEGIN_STRUCT, []int64{}, []string{struct_name}) for i := 0; i < struct_def.Body().BlockStmt().Length(); i++ { stmt_ := struct_def.Body().BlockStmt().Get(i) type_specifier_ := stmt_.VarDeclStmt().TypeSpecifier() field_name := stmt_.VarDeclStmt().Identifier().Attribute() if type_specifier_.TypeSpecifierType() == type_specifier.VOID { if type_specifier_.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } this.relocatable.NewBytecode( abi.APPEND_VOID, []int64{int64(type_specifier_.NumStars())}, []string{field_name}, ) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { this.relocatable.NewBytecode(abi.APPEND_CHAR, []int64{int64(type_specifier_.NumStars())}, []string{field_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { this.relocatable.NewBytecode(abi.APPEND_SHORT, []int64{int64(type_specifier_.NumStars())}, []string{field_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { this.relocatable.NewBytecode(abi.APPEND_INT, []int64{int64(type_specifier_.NumStars())}, []string{field_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { this.relocatable.NewBytecode(abi.APPEND_LONG, []int64{int64(type_specifier_.NumStars())}, []string{field_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { this.relocatable.NewBytecode(abi.APPEND_STRUCT, []int64{int64(type_specifier_.NumStars())}, []string{type_specifier_.StructIdentifier().Attribute(), field_name}) } else { err := errors.New("type specifier type is not valid") panic(err) } } this.relocatable.NewBytecode(abi.END_STRUCT, []int64{}, []string{}) } func (this *Codegen) CodegenFuncDecl(func_decl *decl.FuncDecl) { type_specifier_ := func_decl.TypeSpecifier() method := new(type_system.Method) if type_specifier_.TypeSpecifierType() == type_specifier.VOID { symbol := new(type_system.Symbol) symbol.InitPrimitive( type_system.VOID, type_specifier_.NumStars(), func_decl.Identifier().Attribute(), ) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.CHAR, type_specifier_.NumStars(), func_decl.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.SHORT, type_specifier_.NumStars(), func_decl.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.INT, type_specifier_.NumStars(), func_decl.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.LONG, type_specifier_.NumStars(), func_decl.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { symbol := new(type_system.Symbol) symbol.InitStruct(type_system.STRUCT, type_specifier_.StructIdentifier().Attribute(), type_specifier_.NumStars(), func_decl.Identifier().Attribute()) method.Init(symbol) } else { err := errors.New("type specifier type is not valid") panic(err) } this.type_system.AddMethod(method) for i := 0; i < func_decl.ParamList().Length(); i++ { param := func_decl.ParamList().Get(i) if param.TypeSpecifier().TypeSpecifierType() == type_specifier.VOID { symbol := new(type_system.Symbol) symbol.InitPrimitive( type_system.VOID, param.TypeSpecifier().NumStars(), param.Identifier().Attribute(), ) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.CHAR { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.CHAR, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.SHORT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.SHORT, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.INT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.INT, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.LONG { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.LONG, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.STRUCT { symbol := new(type_system.Symbol) symbol.InitStruct(type_system.STRUCT, param.TypeSpecifier().StructIdentifier().Attribute(), param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else { err := errors.New("type specifier type is not valid") panic(err) } } this.relocatable.NewFunc(func_decl.Identifier().Attribute()) } func (this *Codegen) CodegenFuncDef(func_def *decl.FuncDef) { this.cur_block_depth = 0 type_specifier_ := func_def.TypeSpecifier() func_name := func_def.Identifier().Attribute() if !this.type_system.HasMethod(func_name) { method := new(type_system.Method) if type_specifier_.TypeSpecifierType() == type_specifier.VOID { symbol := new(type_system.Symbol) symbol.InitPrimitive( type_system.VOID, type_specifier_.NumStars(), func_def.Identifier().Attribute(), ) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.CHAR, type_specifier_.NumStars(), func_def.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.SHORT, type_specifier_.NumStars(), func_def.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.INT, type_specifier_.NumStars(), func_def.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.LONG, type_specifier_.NumStars(), func_def.Identifier().Attribute()) method.Init(symbol) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { symbol := new(type_system.Symbol) symbol.InitStruct(type_system.CHAR, type_specifier_.StructIdentifier().Attribute(), type_specifier_.NumStars(), func_def.Identifier().Attribute()) method.Init(symbol) } else { err := errors.New("type specifier type is not valid") panic(err) } this.type_system.AddMethod(method) for i := 0; i < func_def.ParamList().Length(); i++ { param := func_def.ParamList().Get(i) if param.TypeSpecifier().TypeSpecifierType() == type_specifier.VOID { symbol := new(type_system.Symbol) symbol.InitPrimitive( type_system.VOID, param.TypeSpecifier().NumStars(), param.Identifier().Attribute(), ) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.CHAR { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.CHAR, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.SHORT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.SHORT, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.INT { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.INT, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.LONG { symbol := new(type_system.Symbol) symbol.InitPrimitive(type_system.LONG, param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else if param.TypeSpecifier().TypeSpecifierType() == type_specifier.STRUCT { symbol := new(type_system.Symbol) symbol.InitStruct(type_system.STRUCT, param.TypeSpecifier().StructIdentifier().Attribute(), param.TypeSpecifier().NumStars(), param.Identifier().Attribute()) method.AppendParam(symbol) } else { err := errors.New("type specifier type is not valid") panic(err) } } this.relocatable.NewFunc(func_def.Identifier().Attribute()) } this.relocatable.SwitchFunc(func_name) this.relocatable.SwitchLabel(func_name) this.CodegenStmt(func_def.Body()) } func (this *Codegen) CodegenStmt(stmt_ *stmt.Stmt) { if stmt_.StmtType() == stmt.EMPTY { this.CodegenEmptyStmt(stmt_.EmptyStmt()) } else if stmt_.StmtType() == stmt.VAR_DECL { this.CodegenVarDeclStmt(stmt_.VarDeclStmt()) } else if stmt_.StmtType() == stmt.VAR_DECL_INIT { this.CodegenVarDeclInitStmt(stmt_.VarDeclInitStmt()) } else if stmt_.StmtType() == stmt.FOR { this.CodegenForStmt(stmt_.ForStmt()) } else if stmt_.StmtType() == stmt.DPU_FOREACH { this.CodegenDpuForeachStmt(stmt_.DpuForeachStmt()) } else if stmt_.StmtType() == stmt.WHILE { this.CodegenWhileStmt(stmt_.WhileStmt()) } else if stmt_.StmtType() == stmt.CONTINUE { this.CodegenContinueStmt(stmt_.ContinueStmt()) } else if stmt_.StmtType() == stmt.BREAK { this.CodegenBreakStmt(stmt_.BreakStmt()) } else if stmt_.StmtType() == stmt.IF { this.CodegenIfStmt(stmt_.IfStmt()) } else if stmt_.StmtType() == stmt.RETURN { this.CodegenReturnStmt(stmt_.ReturnStmt()) } else if stmt_.StmtType() == stmt.EXPR { this.CodegenExprStmt(stmt_.ExprStmt()) } else if stmt_.StmtType() == stmt.BLOCK { this.CodegenBlockStmt(stmt_.BlockStmt()) } else { err := errors.New("stmt type is not valid") panic(err) } } func (this *Codegen) CodegenEmptyStmt(empty_stmt *stmt.EmptyStmt) { this.relocatable.NewBytecode(abi.NOP, []int64{}, []string{}) } func (this *Codegen) CodegenVarDeclStmt(var_decl_stmt *stmt.VarDeclStmt) { type_specifier_ := var_decl_stmt.TypeSpecifier() symbol_name := var_decl_stmt.Identifier().Attribute() if type_specifier_.TypeSpecifierType() == type_specifier.VOID { if type_specifier_.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } this.relocatable.NewBytecode( abi.NEW_FAST_VOID, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}, ) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { this.relocatable.NewBytecode(abi.NEW_FAST_CHAR, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { this.relocatable.NewBytecode(abi.NEW_FAST_SHORT, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { this.relocatable.NewBytecode(abi.NEW_FAST_INT, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { this.relocatable.NewBytecode(abi.NEW_FAST_LONG, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { this.relocatable.NewBytecode(abi.NEW_FAST_STRUCT, []int64{int64(type_specifier_.NumStars())}, []string{type_specifier_.StructIdentifier().Attribute(), symbol_name}) } else { err := errors.New("type specifier type is not valid") panic(err) } } func (this *Codegen) CodegenVarDeclInitStmt(var_decl_init_stmt *stmt.VarDeclInitStmt) { type_specifier_ := var_decl_init_stmt.TypeSpecifier() symbol_name := var_decl_init_stmt.Identifier().Attribute() if type_specifier_.TypeSpecifierType() == type_specifier.VOID { if type_specifier_.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } this.relocatable.NewBytecode( abi.NEW_FAST_VOID, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}, ) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { this.relocatable.NewBytecode(abi.NEW_FAST_CHAR, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { this.relocatable.NewBytecode(abi.NEW_FAST_SHORT, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { this.relocatable.NewBytecode(abi.NEW_FAST_INT, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { this.relocatable.NewBytecode(abi.NEW_FAST_LONG, []int64{int64(type_specifier_.NumStars())}, []string{symbol_name}) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { this.relocatable.NewBytecode(abi.NEW_FAST_STRUCT, []int64{int64(type_specifier_.NumStars())}, []string{type_specifier_.StructIdentifier().Attribute(), symbol_name}) } else { err := errors.New("type specifier type is not valid") panic(err) } this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{}, []string{symbol_name}) this.CodegenExpr(var_decl_init_stmt.Expr()) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } func (this *Codegen) CodegenForStmt(for_stmt *stmt.ForStmt) { condition_label, body_label, end_label := this.relocatable.NewLoop() this.relocatable.NewBytecode(abi.NEW_SCOPE, []int64{}, []string{}) this.block_depths[condition_label.Name()] = this.cur_block_depth this.cur_block_depth++ this.CodegenStmt(for_stmt.Initialization()) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{condition_label.Name()}) this.relocatable.SwitchLabel(condition_label.Name()) this.CodegenExpr(for_stmt.Condition()) this.relocatable.NewBytecode(abi.JUMP_IF_NONZERO, []int64{}, []string{body_label.Name()}) this.CodegenExpr(for_stmt.Condition()) this.relocatable.NewBytecode(abi.JUMP_IF_ZERO, []int64{}, []string{end_label.Name()}) this.relocatable.SwitchLabel(body_label.Name()) this.CodegenStmt(for_stmt.Body()) this.CodegenStmt(for_stmt.Update()) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{condition_label.Name()}) this.relocatable.SwitchLabel(end_label.Name()) this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) this.cur_block_depth-- } func (this *Codegen) CodegenDpuForeachStmt(dpu_foreach_stmt *stmt.DpuForeachStmt) { if dpu_foreach_stmt.Foreach().Get(1).ExprType() != expr.PRIMARY { err := errors.New("second argument's expr type is not primary") panic(err) } else if dpu_foreach_stmt.Foreach().Get(1).PrimaryExpr().PrimaryExprType() != expr.IDENTIFIER { err := errors.New("second argument's primary expr type is not identifier") panic(err) } dpu_symbol_name := dpu_foreach_stmt.Foreach().Get(1).PrimaryExpr().Token().Attribute() if dpu_foreach_stmt.Foreach().Get(2).ExprType() != expr.PRIMARY { err := errors.New("third argument's expr type is not primary") panic(err) } else if dpu_foreach_stmt.Foreach().Get(2).PrimaryExpr().PrimaryExprType() != expr.IDENTIFIER { err := errors.New("third argument's primary expr type is not identifier") panic(err) } i_symbol_name := dpu_foreach_stmt.Foreach().Get(2).PrimaryExpr().Token().Attribute() this.relocatable.NewBytecode(abi.NEW_SCOPE, []int64{}, []string{}) this.relocatable.NewBytecode(abi.NEW_FAST_INT, []int64{0}, []string{dpu_symbol_name}) this.relocatable.NewBytecode(abi.NEW_FAST_INT, []int64{0}, []string{i_symbol_name}) for i := 0; i < this.num_dpus; i++ { this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{}, []string{dpu_symbol_name}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{int64(i)}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{}, []string{i_symbol_name}) this.relocatable.NewBytecode(abi.PUSH_INT, []int64{int64(i)}, []string{}) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) this.CodegenStmt(dpu_foreach_stmt.Body()) } this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) } func (this *Codegen) CodegenWhileStmt(while_stmt *stmt.WhileStmt) { condition_label, body_label, end_label := this.relocatable.NewLoop() this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{condition_label.Name()}) this.relocatable.SwitchLabel(condition_label.Name()) this.CodegenExpr(while_stmt.Condition()) this.relocatable.NewBytecode(abi.JUMP_IF_NONZERO, []int64{}, []string{body_label.Name()}) this.CodegenExpr(while_stmt.Condition()) this.relocatable.NewBytecode(abi.JUMP_IF_ZERO, []int64{}, []string{end_label.Name()}) this.relocatable.SwitchLabel(body_label.Name()) this.CodegenStmt(while_stmt.Body()) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{condition_label.Name()}) this.relocatable.SwitchLabel(end_label.Name()) } func (this *Codegen) CodegenContinueStmt(continue_stmt *stmt.ContinueStmt) { loop_depth := this.block_depths[this.relocatable.CurLoopCondition().Name()] for i := 0; i < this.cur_block_depth-loop_depth-1; i++ { this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) } this.cur_block_depth = loop_depth this.relocatable.NewBytecode( abi.JUMP, []int64{}, []string{this.relocatable.CurLoopCondition().Name()}, ) } func (this *Codegen) CodegenBreakStmt(break_stmt *stmt.BreakStmt) { loop_depth := this.block_depths[this.relocatable.CurLoopCondition().Name()] for i := 0; i < this.cur_block_depth-loop_depth-1; i++ { this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) } this.cur_block_depth = loop_depth this.relocatable.NewBytecode( abi.JUMP, []int64{}, []string{this.relocatable.CurLoopEnd().Name()}, ) } func (this *Codegen) CodegenIfStmt(if_stmt *stmt.IfStmt) { var num_branches int if if_stmt.HasElseBody() { num_branches = 2 + if_stmt.NumElseIfs() } else { num_branches = 1 + if_stmt.NumElseIfs() } branches := make([]*abi.Label, 0) for i := 0; i < num_branches; i++ { branch := this.relocatable.NewUnnamedLabel() branches = append(branches, branch) } branch_end := this.relocatable.NewUnnamedLabel() this.CodegenExpr(if_stmt.IfCondition()) this.relocatable.NewBytecode(abi.JUMP_IF_NONZERO, []int64{}, []string{branches[0].Name()}) for i := 0; i < if_stmt.NumElseIfs(); i++ { this.CodegenExpr(if_stmt.ElseIfCondition(i)) this.relocatable.NewBytecode(abi.JUMP_IF_NONZERO, []int64{}, []string{branches[i+1].Name()}) } if if_stmt.HasElseBody() { this.relocatable.NewBytecode( abi.JUMP, []int64{}, []string{branches[len(branches)-1].Name()}, ) } else { this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{branch_end.Name()}) } this.relocatable.SwitchLabel(branches[0].Name()) this.CodegenStmt(if_stmt.IfBody()) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{branch_end.Name()}) for i := 0; i < if_stmt.NumElseIfs(); i++ { this.relocatable.SwitchLabel(branches[i+1].Name()) this.CodegenStmt(if_stmt.ElseIfBody(i)) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{branch_end.Name()}) } if if_stmt.HasElseBody() { this.relocatable.SwitchLabel(branches[len(branches)-1].Name()) this.CodegenStmt(if_stmt.ElseBody()) this.relocatable.NewBytecode(abi.JUMP, []int64{}, []string{branch_end.Name()}) } this.relocatable.SwitchLabel(branch_end.Name()) } func (this *Codegen) CodegenReturnStmt(return_stmt *stmt.ReturnStmt) { if return_stmt.HasValue() { func_name := this.relocatable.CurFunc().Name() method := this.type_system.Method(func_name) if method.Symbol().SymbolType() == type_system.VOID { if method.Symbol().NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } this.relocatable.NewBytecode( abi.NEW_RETURN_VOID, []int64{int64(method.Symbol().NumStars())}, []string{}, ) } else if method.Symbol().SymbolType() == type_system.CHAR { this.relocatable.NewBytecode(abi.NEW_RETURN_CHAR, []int64{int64(method.Symbol().NumStars())}, []string{}) } else if method.Symbol().SymbolType() == type_system.SHORT { this.relocatable.NewBytecode(abi.NEW_RETURN_SHORT, []int64{int64(method.Symbol().NumStars())}, []string{}) } else if method.Symbol().SymbolType() == type_system.INT { this.relocatable.NewBytecode(abi.NEW_RETURN_INT, []int64{int64(method.Symbol().NumStars())}, []string{}) } else if method.Symbol().SymbolType() == type_system.LONG { this.relocatable.NewBytecode(abi.NEW_RETURN_LONG, []int64{int64(method.Symbol().NumStars())}, []string{}) } else if method.Symbol().SymbolType() == type_system.STRUCT { this.relocatable.NewBytecode(abi.NEW_RETURN_STRUCT, []int64{int64(method.Symbol().NumStars())}, []string{method.Symbol().StructName()}) } else { err := errors.New("symbol type is not valid") panic(err) } this.CodegenExpr(return_stmt.Value()) this.relocatable.NewBytecode(abi.ASSIGN_RETURN, []int64{}, []string{}) } this.relocatable.NewBytecode(abi.RETURN, []int64{}, []string{}) } func (this *Codegen) CodegenExprStmt(expr_stmt *stmt.ExprStmt) { this.CodegenExpr(expr_stmt.Expr()) } func (this *Codegen) CodegenBlockStmt(block_stmt *stmt.BlockStmt) { this.relocatable.NewBytecode(abi.NEW_SCOPE, []int64{}, []string{}) this.block_depths[this.relocatable.CurLabel().Name()] = this.cur_block_depth this.cur_block_depth++ for i := 0; i < block_stmt.Length(); i++ { stmt_ := block_stmt.Get(i) this.CodegenStmt(stmt_) } this.relocatable.NewBytecode(abi.DELETE_SCOPE, []int64{}, []string{}) this.cur_block_depth-- } func (this *Codegen) CodegenExpr(expr_ *expr.Expr) { if expr_.ExprType() == expr.PRIMARY { this.CodegenPrimaryExpr(expr_.PrimaryExpr()) } else if expr_.ExprType() == expr.POSTFIX { this.CodegenPostfixExpr(expr_.PostfixExpr()) } else if expr_.ExprType() == expr.UNARY { this.CodegenUnaryExpr(expr_.UnaryExpr()) } else if expr_.ExprType() == expr.MULTIPLICATIVE { this.CodegenMultiplicativeExpr(expr_.MultiplicativeExpr()) } else if expr_.ExprType() == expr.ADDITIVE { this.CodegenAdditiveExpr(expr_.AdditiveExpr()) } else if expr_.ExprType() == expr.SHIFT { this.CodegenShiftExpr(expr_.ShiftExpr()) } else if expr_.ExprType() == expr.RELATIONAL { this.CodegenRelationalExpr(expr_.RelationalExpr()) } else if expr_.ExprType() == expr.EQUALITY { this.CodegenEqualityExpr(expr_.EqualityExpr()) } else if expr_.ExprType() == expr.BITWISE_AND { this.CodegenBitwiseAndExpr(expr_.BitwiseAndExpr()) } else if expr_.ExprType() == expr.BITWISE_XOR { this.CodegenBitwiseXorExpr(expr_.BitwiseXorExpr()) } else if expr_.ExprType() == expr.BITWISE_OR { this.CodegenBitwiseOrExpr(expr_.BitwiseOrExpr()) } else if expr_.ExprType() == expr.LOGICAL_AND { this.CodegenLogicalAndExpr(expr_.LogicalAndExpr()) } else if expr_.ExprType() == expr.LOGICAL_OR { this.CodegenLogicalOrExpr(expr_.LogicalOrExpr()) } else if expr_.ExprType() == expr.CONDITIONAL { this.CodegenConditionalExpr(expr_.ConditionalExpr()) } else if expr_.ExprType() == expr.ASSIGNMENT { this.CodegenAssignmentExpr(expr_.AssignmentExpr()) } else { err := errors.New("expr type is not valid") panic(err) } } func (this *Codegen) CodegenPrimaryExpr(primary_expr *expr.PrimaryExpr) { if primary_expr.PrimaryExprType() == expr.IDENTIFIER { symbol_name := primary_expr.Token().Attribute() if symbol_name == "DPU_XFER_TO_DPU" { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{0}, []string{}) } else if symbol_name == "DPU_XFER_FROM_DPU" { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{1}, []string{}) } else if symbol_name == "DPU_MRAM_HEAP_POINTER_NAME" { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{this.dpu_mram_heap_pointer_name}, []string{}) } else if symbol_name == "DPU_XFER_DEFAULT" { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{0}, []string{}) } else if symbol_name == "DPU_SYNCHRONOUS" { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{0}, []string{}) } else { this.relocatable.NewBytecode(abi.GET_IDENTIFIER, []int64{}, []string{symbol_name}) } } else if primary_expr.PrimaryExprType() == expr.NUMBER { number, err := strconv.ParseInt(primary_expr.Token().Attribute(), 10, 64) if err != nil { panic(err) } this.relocatable.NewBytecode(abi.PUSH_INT, []int64{number}, []string{}) } else if primary_expr.PrimaryExprType() == expr.STRING { str := primary_expr.Token().Attribute() this.relocatable.NewBytecode(abi.PUSH_STRING, []int64{}, []string{str}) } else if primary_expr.PrimaryExprType() == expr.NULLPTR { this.relocatable.NewBytecode(abi.PUSH_INT, []int64{0}, []string{}) } else if primary_expr.PrimaryExprType() == expr.PAREN { this.CodegenExpr(primary_expr.Expr()) } else { err := errors.New("primary expr type is not valid") panic(err) } } func (this *Codegen) CodegenPostfixExpr(postfix_expr *expr.PostfixExpr) { if postfix_expr.PostfixExprType() == expr.BRACKET { this.CodegenExpr(postfix_expr.Base()) this.CodegenExpr(postfix_expr.OffsetExpr()) this.relocatable.NewBytecode(abi.GET_SUBSCRIPT, []int64{}, []string{}) } else if postfix_expr.PostfixExprType() == expr.CALL { if postfix_expr.Base().ExprType() != expr.PRIMARY { err := errors.New("base expr type is not primary") panic(err) } else if postfix_expr.Base().PrimaryExpr().PrimaryExprType() != expr.IDENTIFIER { err := errors.New("base primary expr type is not identifier") panic(err) } func_name := postfix_expr.Base().PrimaryExpr().Token().Attribute() if func_name == "malloc" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.ALLOC, []int64{}, []string{}) } else if func_name == "free" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.FREE, []int64{}, []string{}) } else if func_name == "assert" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.ASSERT, []int64{}, []string{}) } else if func_name == "sqrt" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.SQRT, []int64{}, []string{}) } else if func_name == "dpu_alloc" { for i := 0; i < this.num_dpus; i++ { this.relocatable.NewBytecode(abi.DPU_ALLOC, []int64{int64(i)}, []string{}) } } else if func_name == "dpu_load" { for i := 0; i < this.num_dpus; i++ { this.relocatable.NewBytecode(abi.DPU_LOAD, []int64{int64(i)}, []string{this.benchmark}) } } else if func_name == "dpu_prepare_xfer" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_PREPARE, []int64{}, []string{}) } else if func_name == "dpu_push_xfer" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_TRANSFER, []int64{}, []string{}) } else if func_name == "dpu_copy_to" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_COPY_TO, []int64{}, []string{}) } else if func_name == "dpu_copy_from" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_COPY_FROM, []int64{}, []string{}) } else if func_name == "dpu_launch" { for i := 0; i < postfix_expr.ArgList().Length(); i++ { this.CodegenExpr(postfix_expr.ArgList().Get(i)) } this.relocatable.NewBytecode(abi.DPU_LAUNCH, []int64{}, []string{}) } else if func_name == "dpu_free" { this.relocatable.NewBytecode(abi.DPU_FREE, []int64{}, []string{}) } else { method := this.type_system.Method(func_name) params := method.Params() for i, param := range params { arg := postfix_expr.ArgList().Get(i) if param.SymbolType() == type_system.VOID { this.relocatable.NewBytecode(abi.NEW_ARG_VOID, []int64{int64(param.NumStars())}, []string{param.Name()}) } else if param.SymbolType() == type_system.CHAR { this.relocatable.NewBytecode(abi.NEW_ARG_CHAR, []int64{int64(param.NumStars())}, []string{param.Name()}) } else if param.SymbolType() == type_system.SHORT { this.relocatable.NewBytecode(abi.NEW_ARG_SHORT, []int64{int64(param.NumStars())}, []string{param.Name()}) } else if param.SymbolType() == type_system.INT { this.relocatable.NewBytecode(abi.NEW_ARG_INT, []int64{int64(param.NumStars())}, []string{param.Name()}) } else if param.SymbolType() == type_system.LONG { this.relocatable.NewBytecode(abi.NEW_ARG_LONG, []int64{int64(param.NumStars())}, []string{param.Name()}) } else if param.SymbolType() == type_system.STRUCT { this.relocatable.NewBytecode(abi.NEW_ARG_STRUCT, []int64{int64(param.NumStars())}, []string{param.StructName(), param.Name()}) } else { err := errors.New("symbol type is not valid") panic(err) } this.relocatable.NewBytecode(abi.GET_ARG_IDENTIFIER, []int64{0}, []string{param.Name()}) this.CodegenExpr(arg) this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } this.relocatable.NewBytecode(abi.CALL, []int64{}, []string{func_name}) } } else if postfix_expr.PostfixExprType() == expr.DOT { field_name := postfix_expr.OffsetToken().Attribute() this.CodegenExpr(postfix_expr.Base()) this.relocatable.NewBytecode(abi.GET_ACCESS, []int64{}, []string{field_name}) } else if postfix_expr.PostfixExprType() == expr.ARROW { field_name := postfix_expr.OffsetToken().Attribute() this.CodegenExpr(postfix_expr.Base()) this.relocatable.NewBytecode(abi.GET_REFERENCE, []int64{}, []string{field_name}) } else if postfix_expr.PostfixExprType() == expr.POSTFIX_PLUS_PLUS { this.CodegenExpr(postfix_expr.Base()) this.relocatable.NewBytecode(abi.ASSIGN_PLUS_PLUS, []int64{}, []string{}) } else if postfix_expr.PostfixExprType() == expr.POSTFIX_MINUS_MINUS { this.CodegenExpr(postfix_expr.Base()) this.relocatable.NewBytecode(abi.ASSIGN_MINUS_MINUS, []int64{}, []string{}) } else { err := errors.New("postfix expr type is not valid") panic(err) } } func (this *Codegen) CodegenUnaryExpr(unary_expr *expr.UnaryExpr) { if unary_expr.UnaryExprType() == expr.UNARY_PLUS_PLUS { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.ASSIGN_PLUS_PLUS, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.UNARY_MINUS_MINUS { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.ASSIGN_MINUS_MINUS, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.AND { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.GET_ADDRESS, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.STAR { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.GET_VALUE, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.PLUS { this.CodegenExpr(unary_expr.Base()) } else if unary_expr.UnaryExprType() == expr.MINUS { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.NEGATE, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.TILDE { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.TILDE, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.NOT { this.CodegenExpr(unary_expr.Base()) this.relocatable.NewBytecode(abi.LOGICAL_NOT, []int64{}, []string{}) } else if unary_expr.UnaryExprType() == expr.SIZEOF { type_specifier_ := unary_expr.TypeSpecifier() if type_specifier_.TypeSpecifierType() == type_specifier.VOID { if type_specifier_.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } this.relocatable.NewBytecode(abi.SIZEOF_VOID, []int64{int64(type_specifier_.NumStars())}, []string{}) } else if type_specifier_.TypeSpecifierType() == type_specifier.CHAR { this.relocatable.NewBytecode(abi.SIZEOF_CHAR, []int64{int64(type_specifier_.NumStars())}, []string{}) } else if type_specifier_.TypeSpecifierType() == type_specifier.SHORT { this.relocatable.NewBytecode(abi.SIZEOF_SHORT, []int64{int64(type_specifier_.NumStars())}, []string{}) } else if type_specifier_.TypeSpecifierType() == type_specifier.INT { this.relocatable.NewBytecode(abi.SIZEOF_INT, []int64{int64(type_specifier_.NumStars())}, []string{}) } else if type_specifier_.TypeSpecifierType() == type_specifier.LONG { this.relocatable.NewBytecode(abi.SIZEOF_LONG, []int64{int64(type_specifier_.NumStars())}, []string{}) } else if type_specifier_.TypeSpecifierType() == type_specifier.STRUCT { this.relocatable.NewBytecode(abi.SIZEOF_STRUCT, []int64{int64(type_specifier_.NumStars())}, []string{type_specifier_.StructIdentifier().Attribute()}) } else { err := errors.New("type specifier type is not valid") panic(err) } } else { err := errors.New("unary expr type is not valid") panic(err) } } func (this *Codegen) CodegenMultiplicativeExpr(multiplicative_expr *expr.MultiplicativeExpr) { this.CodegenExpr(multiplicative_expr.Loperand()) this.CodegenExpr(multiplicative_expr.Roperand()) if multiplicative_expr.MultiplicativeExprType() == expr.MUL { this.relocatable.NewBytecode(abi.MUL, []int64{}, []string{}) } else if multiplicative_expr.MultiplicativeExprType() == expr.DIV { this.relocatable.NewBytecode(abi.DIV, []int64{}, []string{}) } else if multiplicative_expr.MultiplicativeExprType() == expr.MOD { this.relocatable.NewBytecode(abi.MOD, []int64{}, []string{}) } else { err := errors.New("multiplicative expr type is not valid") panic(err) } } func (this *Codegen) CodegenAdditiveExpr(additive_expr *expr.AdditiveExpr) { this.CodegenExpr(additive_expr.Loperand()) this.CodegenExpr(additive_expr.Roperand()) if additive_expr.AdditiveExprType() == expr.ADD { this.relocatable.NewBytecode(abi.ADD, []int64{}, []string{}) } else if additive_expr.AdditiveExprType() == expr.SUB { this.relocatable.NewBytecode(abi.SUB, []int64{}, []string{}) } else { err := errors.New("additive expr type is not valid") panic(err) } } func (this *Codegen) CodegenShiftExpr(shift_expr *expr.ShiftExpr) { this.CodegenExpr(shift_expr.Loperand()) this.CodegenExpr(shift_expr.Roperand()) if shift_expr.ShiftExprType() == expr.LSHIFT { this.relocatable.NewBytecode(abi.LSHIFT, []int64{}, []string{}) } else if shift_expr.ShiftExprType() == expr.RSHIFT { this.relocatable.NewBytecode(abi.RSHIFT, []int64{}, []string{}) } else { err := errors.New("shift expr type is not valid") panic(err) } } func (this *Codegen) CodegenRelationalExpr(relational_expr *expr.RelationalExpr) { this.CodegenExpr(relational_expr.Loperand()) this.CodegenExpr(relational_expr.Roperand()) if relational_expr.RelationalExprType() == expr.LESS { this.relocatable.NewBytecode(abi.LESS, []int64{}, []string{}) } else if relational_expr.RelationalExprType() == expr.LESS_EQ { this.relocatable.NewBytecode(abi.LESS_EQ, []int64{}, []string{}) } else if relational_expr.RelationalExprType() == expr.GREATER { this.relocatable.NewBytecode(abi.GREATER, []int64{}, []string{}) } else if relational_expr.RelationalExprType() == expr.GREATER_EQ { this.relocatable.NewBytecode(abi.GREATER_EQ, []int64{}, []string{}) } else { err := errors.New("relational expr type is not valid") panic(err) } } func (this *Codegen) CodegenEqualityExpr(equality_expr *expr.EqualityExpr) { this.CodegenExpr(equality_expr.Loperand()) this.CodegenExpr(equality_expr.Roperand()) if equality_expr.EqualityExprType() == expr.EQ { this.relocatable.NewBytecode(abi.EQ, []int64{}, []string{}) } else if equality_expr.EqualityExprType() == expr.NOT_EQ { this.relocatable.NewBytecode(abi.NOT_EQ, []int64{}, []string{}) } else { err := errors.New("equality expr type is not valid") panic(err) } } func (this *Codegen) CodegenBitwiseAndExpr(bitwise_and_expr *expr.BitwiseAndExpr) { this.CodegenExpr(bitwise_and_expr.Loperand()) this.CodegenExpr(bitwise_and_expr.Roperand()) this.relocatable.NewBytecode(abi.BITWISE_AND, []int64{}, []string{}) } func (this *Codegen) CodegenBitwiseXorExpr(bitwise_xor_expr *expr.BitwiseXorExpr) { this.CodegenExpr(bitwise_xor_expr.Loperand()) this.CodegenExpr(bitwise_xor_expr.Roperand()) this.relocatable.NewBytecode(abi.BITWISE_XOR, []int64{}, []string{}) } func (this *Codegen) CodegenBitwiseOrExpr(bitwise_or_expr *expr.BitwiseOrExpr) { this.CodegenExpr(bitwise_or_expr.Loperand()) this.CodegenExpr(bitwise_or_expr.Roperand()) this.relocatable.NewBytecode(abi.BITWISE_OR, []int64{}, []string{}) } func (this *Codegen) CodegenLogicalAndExpr(logical_and_expr *expr.LogicalAndExpr) { this.CodegenExpr(logical_and_expr.Loperand()) this.CodegenExpr(logical_and_expr.Roperand()) this.relocatable.NewBytecode(abi.LOGICAL_AND, []int64{}, []string{}) } func (this *Codegen) CodegenLogicalOrExpr(logical_or_expr *expr.LogicalOrExpr) { this.CodegenExpr(logical_or_expr.Loperand()) this.CodegenExpr(logical_or_expr.Roperand()) this.relocatable.NewBytecode(abi.LOGICAL_OR, []int64{}, []string{}) } func (this *Codegen) CodegenConditionalExpr(conditional_expr *expr.ConditionalExpr) { this.CodegenExpr(conditional_expr.ConditionalExpr()) this.CodegenExpr(conditional_expr.TrueExpr()) this.CodegenExpr(conditional_expr.FalseExpr()) this.relocatable.NewBytecode(abi.CONDITIONAL, []int64{}, []string{}) } func (this *Codegen) CodegenAssignmentExpr(assignment_expr *expr.AssignmentExpr) { this.CodegenExpr(assignment_expr.Lvalue()) this.CodegenExpr(assignment_expr.Rvalue()) if assignment_expr.AssignmentExprType() == expr.ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.STAR_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_STAR, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.DIV_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_DIV, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.MOD_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_MOD, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.PLUS_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_ADD, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.MINUS_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_SUB, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.LSHIFT_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_LSHIFT, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.RSHIFT_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_RSHIFT, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.AND_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_BITWISE_AND, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.CARET_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_BITWISE_XOR, []int64{}, []string{}) } else if assignment_expr.AssignmentExprType() == expr.OR_ASSIGN { this.relocatable.NewBytecode(abi.ASSIGN_BITWISE_OR, []int64{}, []string{}) } else { err := errors.New("assignment expr type is not valid") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/codegen/type_system/method.go ================================================ package type_system import ( "errors" "fmt" ) type Method struct { symbol *Symbol params []*Symbol } func (this *Method) Init(symbol *Symbol) { this.symbol = symbol this.params = make([]*Symbol, 0) } func (this *Method) Symbol() *Symbol { return this.symbol } func (this *Method) HasParam(param_name string) bool { for _, param := range this.params { if param.Name() == param_name { return true } } return false } func (this *Method) Param(param_name string) *Symbol { if !this.HasParam(param_name) { err_msg := fmt.Sprintf("param (%s) is not found", param_name) err := errors.New(err_msg) panic(err) } for _, param := range this.params { if param.Name() == param_name { return param } } return nil } func (this *Method) Params() []*Symbol { return this.params } func (this *Method) AppendParam(param *Symbol) { this.params = append(this.params, param) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/codegen/type_system/symbol.go ================================================ package type_system import ( "errors" ) type SymbolType int const ( VOID SymbolType = iota CHAR SHORT INT LONG STRING STRUCT ) type Symbol struct { symbol_type SymbolType struct_name *string num_stars int name string } func (this *Symbol) InitPrimitive(symbol_type SymbolType, num_stars int, name string) { if symbol_type == STRUCT { err := errors.New("symbol type is struct") panic(err) } this.symbol_type = symbol_type this.struct_name = nil this.num_stars = num_stars this.name = name } func (this *Symbol) InitStruct( symbol_type SymbolType, struct_name string, num_stars int, name string, ) { if symbol_type != STRUCT { err := errors.New("symbol type is not struct") panic(err) } this.symbol_type = symbol_type this.struct_name = new(string) *this.struct_name = struct_name this.num_stars = num_stars this.name = name } func (this *Symbol) SymbolType() SymbolType { return this.symbol_type } func (this *Symbol) StructName() string { if this.struct_name == nil { err := errors.New("struct name == nil") panic(err) } return *this.struct_name } func (this *Symbol) NumStars() int { return this.num_stars } func (this *Symbol) Name() string { return this.name } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/codegen/type_system/type_system.go ================================================ package type_system import ( "errors" "fmt" ) type TypeSystem struct { methods map[string]*Method } func (this *TypeSystem) Init() { this.methods = make(map[string]*Method) } func (this *TypeSystem) HasMethod(method_name string) bool { _, found := this.methods[method_name] return found } func (this *TypeSystem) Method(method_name string) *Method { if !this.HasMethod(method_name) { err_msg := fmt.Sprintf("method (%s) is not found", method_name) err := errors.New(err_msg) panic(err) } return this.methods[method_name] } func (this *TypeSystem) AddMethod(method *Method) { this.methods[method.Symbol().Name()] = method } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/interpreter.go ================================================ package interpreter import ( "path/filepath" "uPIMulator/src/host/abi" "uPIMulator/src/host/interpreter/codegen" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser" "uPIMulator/src/misc" ) type Interpreter struct { root_dirpath string bin_dirpath string benchmark string num_dpus int num_tasklets int data_prep_params int dpu_mram_heap_pointer_name int64 binary *abi.Binary } func (this *Interpreter) Init( command_line_parser *misc.CommandLineParser, dpu_mram_heap_pointer_name int64, ) { this.root_dirpath = command_line_parser.StringParameter("root_dirpath") this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = num_channels * num_ranks_per_channel * num_dpus_per_rank this.num_tasklets = int(command_line_parser.IntParameter("num_tasklets")) this.data_prep_params = int(command_line_parser.IntParameter("data_prep_params")) this.dpu_mram_heap_pointer_name = dpu_mram_heap_pointer_name this.binary = new(abi.Binary) this.binary.Init(this.benchmark, this.num_dpus, this.num_tasklets) } func (this *Interpreter) Interpret() { this.Lex() this.Parse() this.Codegen() binary_path := filepath.Join(this.bin_dirpath, "bytecode.txt") this.binary.Dump(binary_path) } func (this *Interpreter) Lex() { source_code := this.FindSourceCode() lexer_ := new(lexer.Lexer) lexer_.Init() token_stream := lexer_.Lex(source_code) this.binary.SetTokenStream(token_stream) } func (this *Interpreter) Parse() { parser_ := new(parser.Parser) parser_.Init() ast := parser_.Parse(this.binary.TokenStream()) this.binary.SetAst(ast) } func (this *Interpreter) Codegen() { codegen_ := new(codegen.Codegen) codegen_.Init( this.benchmark, this.num_dpus, this.num_tasklets, this.data_prep_params, this.dpu_mram_heap_pointer_name, ) relocatable := codegen_.Codegen(this.binary.Ast()) this.binary.SetRelocatable(relocatable) } func (this *Interpreter) FindSourceCode() string { benchmark_dirpath := filepath.Join(this.root_dirpath, "benchmark", this.benchmark) c_path := filepath.Join(benchmark_dirpath, "host", "app.c") return c_path } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/keyword_factory.go ================================================ package lexer import ( "errors" ) type KeywordFactory struct { keywords map[string]TokenType } func (this *KeywordFactory) Init() { this.keywords = make(map[string]TokenType) } func (this *KeywordFactory) AddKeyword(keyword string, token_type TokenType) { this.keywords[keyword] = token_type } func (this *KeywordFactory) IsTokenizable(word string) bool { _, found := this.keywords[word] return found } func (this *KeywordFactory) Tokenize(word string) *Token { if _, found := this.keywords[word]; !found { err := errors.New("word is not tokenizable") panic(err) } token_type := this.keywords[word] token := new(Token) token.Init(token_type, "") return token } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/lexer.go ================================================ package lexer import ( "errors" "strings" "uPIMulator/src/misc" ) type Lexer struct { tokenizer *Tokenizer } func (this *Lexer) Init() { this.tokenizer = new(Tokenizer) this.tokenizer.Init() } func (this *Lexer) Lex(path string) *TokenStream { file_scanner := new(misc.FileScanner) file_scanner.Init(path) token_stream := new(TokenStream) token_stream.Init() for _, line := range file_scanner.ReadLines() { line = strings.Replace(line, "\n", "", -1) token_stream.Merge(this.Tokenize(line)) } end_of_file := new(Token) end_of_file.Init(END_OF_FILE, "") token_stream.Append(end_of_file) return token_stream } func (this *Lexer) Tokenize(line string) *TokenStream { token_stream := new(TokenStream) token_stream.Init() prev_pos := 0 for prev_pos < len(line) { if token_stream.Length() > 0 { last_token := token_stream.Get(token_stream.Length() - 1) if last_token.TokenType() == INCLUDE { token := this.FindHeader(line, prev_pos) token_stream.Append(token) return token_stream } } token, length := this.FindTokenWithMaxLength(line, prev_pos) if token != nil { token_stream.Append(token) } prev_pos += length } return token_stream } func (this *Lexer) FindHeader(line string, prev_pos int) *Token { for this.IsWhiteSpace(string(line[prev_pos])) { prev_pos++ } word := line[prev_pos:] token := this.tokenizer.Tokenize(word) return token } func (this *Lexer) FindTokenWithMaxLength(line string, prev_pos int) (*Token, int) { if prev_pos < 0 { err := errors.New("prev pos < 0") panic(err) } if this.IsWhiteSpace(string(line[prev_pos])) { return nil, 1 } if this.IsQuote(string(line[prev_pos])) { next_quote_pos := this.FindNextQuote(line, prev_pos+1) word := line[prev_pos : next_quote_pos+1] token := this.tokenizer.Tokenize(word) return token, next_quote_pos - prev_pos + 1 } for i := prev_pos + 1; i <= len(line); i++ { word := line[prev_pos:i] if i+1 <= len(line) { next_word := line[prev_pos : i+1] if this.tokenizer.IsTokenizable(word) && !this.tokenizer.IsTokenizable(next_word) { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } } else { token := this.tokenizer.Tokenize(word) return token, i - prev_pos } } err := errors.New("line is not further tokenizable") panic(err) } func (this *Lexer) IsWhiteSpace(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == " " || word == "\t" || word == "\n" } func (this *Lexer) IsQuote(word string) bool { if len(word) != 1 { err := errors.New("word size != 1") panic(err) } return word == "\"" } func (this *Lexer) FindNextQuote(line string, pos int) int { for i := pos; i < len(line); i++ { if this.IsQuote(string(line[i])) { return i } } err := errors.New("line does not have the next quote") panic(err) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/regex.go ================================================ package lexer import ( "errors" "regexp" ) type Regex struct { expr string regex *regexp.Regexp token_type TokenType } func (this *Regex) Init(expr string, token_type TokenType) { this.expr = expr regex, err := regexp.Compile(expr) if err != nil { panic(err) } this.regex = regex this.token_type = token_type } func (this *Regex) Expr() string { return this.expr } func (this *Regex) TokenType() TokenType { return this.token_type } func (this *Regex) IsTokenizable(word string) bool { return this.regex.MatchString(word) } func (this *Regex) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not matched") panic(err) } token := new(Token) token.Init(this.token_type, word) return token } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/regex_factory.go ================================================ package lexer import ( "errors" ) type RegexFactory struct { regexes []*Regex } func (this *RegexFactory) Init() { this.regexes = make([]*Regex, 0) } func (this *RegexFactory) HasRegex(expr string) bool { for _, regex := range this.regexes { if regex.Expr() == expr { return true } } return false } func (this *RegexFactory) AddRegex(expr string, token_type TokenType) { if this.HasRegex(expr) { err := errors.New("regex already exists") panic(err) } regex := new(Regex) regex.Init(expr, token_type) this.regexes = append(this.regexes, regex) } func (this *RegexFactory) IsTokenizable(word string) bool { for _, regex := range this.regexes { if regex.IsTokenizable(word) { return true } } return false } func (this *RegexFactory) Tokenize(word string) *Token { if !this.IsTokenizable(word) { err := errors.New("word is not tokenizable") panic(err) } for _, regex := range this.regexes { if regex.IsTokenizable(word) { token := new(Token) token.Init(regex.TokenType(), word) return token } } return nil } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/token.go ================================================ package lexer type TokenType int const ( END_OF_FILE TokenType = iota IDENTIFIER NUMBER STRING HEADER INCLUDE DEFINE IFNDEF IFDEF BEGINIF ENDIF BREAK CHAR CONTINUE ELSE FOR IF INT LONG NULL RETURN SHORT SIZEOF STRUCT VOID WHILE LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE LESS LESS_EQ GREATER GREATER_EQ EQ NOT_EQ PLUS PLUS_PLUS MINUS MINUS_MINUS STAR DIV MOD LSHIFT RSHIFT AND AND_AND OR OR_OR CARET NOT TILDE QUESTION SEMI COLON COMMA ASSIGN PLUS_ASSIGN MINUS_ASSIGN STAR_ASSIGN DIV_ASSIGN MOD_ASSIGN LSHIFT_ASSIGN RSHIFT_ASSIGN AND_ASSIGN OR_ASSIGN CARET_ASSIGN ARROW DOT ) type Token struct { token_type TokenType attribute string } func (this *Token) Init(token_type TokenType, attribute string) { this.token_type = token_type this.attribute = attribute } func (this *Token) TokenType() TokenType { return this.token_type } func (this *Token) Attribute() string { return this.attribute } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/token_stream.go ================================================ package lexer type TokenStream struct { tokens []*Token } func (this *TokenStream) Init() { this.tokens = make([]*Token, 0) } func (this *TokenStream) Length() int { return len(this.tokens) } func (this *TokenStream) Get(pos int) *Token { return this.tokens[pos] } func (this *TokenStream) Append(token *Token) { this.tokens = append(this.tokens, token) } func (this *TokenStream) Merge(token_stream *TokenStream) { for i := 0; i < token_stream.Length(); i++ { this.Append(token_stream.Get(i)) } } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/lexer/tokenizer.go ================================================ package lexer import ( "errors" ) type Tokenizer struct { keyword_factory *KeywordFactory regex_factory *RegexFactory } func (this *Tokenizer) Init() { this.InitKeywordFactory() this.InitRegexFactory() } func (this *Tokenizer) InitKeywordFactory() { this.keyword_factory = new(KeywordFactory) this.keyword_factory.Init() this.keyword_factory.AddKeyword("#include", INCLUDE) this.keyword_factory.AddKeyword("#define", DEFINE) this.keyword_factory.AddKeyword("#ifndef", IFNDEF) this.keyword_factory.AddKeyword("#ifdef", IFDEF) this.keyword_factory.AddKeyword("#if", BEGINIF) this.keyword_factory.AddKeyword("#endif", ENDIF) this.keyword_factory.AddKeyword("break", BREAK) this.keyword_factory.AddKeyword("char", CHAR) this.keyword_factory.AddKeyword("continue", CONTINUE) this.keyword_factory.AddKeyword("else", ELSE) this.keyword_factory.AddKeyword("for", FOR) this.keyword_factory.AddKeyword("if", IF) this.keyword_factory.AddKeyword("int", INT) this.keyword_factory.AddKeyword("long", LONG) this.keyword_factory.AddKeyword("NULL", NULL) this.keyword_factory.AddKeyword("return", RETURN) this.keyword_factory.AddKeyword("short", SHORT) this.keyword_factory.AddKeyword("sizeof", SIZEOF) this.keyword_factory.AddKeyword("struct", STRUCT) this.keyword_factory.AddKeyword("void", VOID) this.keyword_factory.AddKeyword("while", WHILE) this.keyword_factory.AddKeyword("(", LPAREN) this.keyword_factory.AddKeyword(")", RPAREN) this.keyword_factory.AddKeyword("[", LBRACKET) this.keyword_factory.AddKeyword("]", RBRACKET) this.keyword_factory.AddKeyword("{", LBRACE) this.keyword_factory.AddKeyword("}", RBRACE) this.keyword_factory.AddKeyword("<", LESS) this.keyword_factory.AddKeyword("<=", LESS_EQ) this.keyword_factory.AddKeyword(">", GREATER) this.keyword_factory.AddKeyword(">=", GREATER_EQ) this.keyword_factory.AddKeyword("==", EQ) this.keyword_factory.AddKeyword("!=", NOT_EQ) this.keyword_factory.AddKeyword("+", PLUS) this.keyword_factory.AddKeyword("++", PLUS_PLUS) this.keyword_factory.AddKeyword("-", MINUS) this.keyword_factory.AddKeyword("--", MINUS_MINUS) this.keyword_factory.AddKeyword("*", STAR) this.keyword_factory.AddKeyword("/", DIV) this.keyword_factory.AddKeyword("%", MOD) this.keyword_factory.AddKeyword("<<", LSHIFT) this.keyword_factory.AddKeyword(">>", RSHIFT) this.keyword_factory.AddKeyword("&", AND) this.keyword_factory.AddKeyword("&&", AND_AND) this.keyword_factory.AddKeyword("|", OR) this.keyword_factory.AddKeyword("||", OR_OR) this.keyword_factory.AddKeyword("^", CARET) this.keyword_factory.AddKeyword("!", NOT) this.keyword_factory.AddKeyword("~", TILDE) this.keyword_factory.AddKeyword("?", QUESTION) this.keyword_factory.AddKeyword(";", SEMI) this.keyword_factory.AddKeyword(":", COLON) this.keyword_factory.AddKeyword(",", COMMA) this.keyword_factory.AddKeyword("=", ASSIGN) this.keyword_factory.AddKeyword("+=", PLUS_ASSIGN) this.keyword_factory.AddKeyword("-=", MINUS_ASSIGN) this.keyword_factory.AddKeyword("*=", STAR_ASSIGN) this.keyword_factory.AddKeyword("/=", DIV_ASSIGN) this.keyword_factory.AddKeyword("%=", MOD_ASSIGN) this.keyword_factory.AddKeyword("<<=", LSHIFT_ASSIGN) this.keyword_factory.AddKeyword(">>=", RSHIFT_ASSIGN) this.keyword_factory.AddKeyword("&=", AND_ASSIGN) this.keyword_factory.AddKeyword("|=", OR_ASSIGN) this.keyword_factory.AddKeyword("^=", CARET_ASSIGN) this.keyword_factory.AddKeyword("->", ARROW) this.keyword_factory.AddKeyword(".", DOT) } func (this *Tokenizer) InitRegexFactory() { this.regex_factory = new(RegexFactory) this.regex_factory.Init() this.regex_factory.AddRegex("^([A-Za-z_])([A-Za-z0-9_]*)$", IDENTIFIER) this.regex_factory.AddRegex("^([0-9]+)$", NUMBER) this.regex_factory.AddRegex("^\"([A-Za-z0-9/_.])*\"$", STRING) this.regex_factory.AddRegex("^<([A-Za-z0-9/_.]*)>$", HEADER) } func (this *Tokenizer) IsTokenizable(word string) bool { return this.keyword_factory.IsTokenizable(word) || this.regex_factory.IsTokenizable(word) } func (this *Tokenizer) Tokenize(word string) *Token { if this.keyword_factory.IsTokenizable(word) { return this.keyword_factory.Tokenize(word) } else if this.regex_factory.IsTokenizable(word) { return this.regex_factory.Tokenize(word) } else { err := errors.New("word is not tokenizable") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/ast.go ================================================ package parser type Ast struct { stack_items []*StackItem } func (this *Ast) Init(stack_items []*StackItem) { this.stack_items = stack_items } func (this *Ast) Length() int { return len(this.stack_items) } func (this *Ast) Get(pos int) *StackItem { return this.stack_items[pos] } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/decl/decl.go ================================================ package decl type DeclType int const ( STRUCT_DEF DeclType = iota FUNC_DECL FUNC_DEF ) type Decl struct { decl_type DeclType struct_def *StructDef func_decl *FuncDecl func_def *FuncDef } func (this *Decl) InitStructDef(struct_def *StructDef) { this.decl_type = STRUCT_DEF this.struct_def = struct_def } func (this *Decl) InitFuncDecl(func_decl *FuncDecl) { this.decl_type = FUNC_DECL this.func_decl = func_decl } func (this *Decl) InitFuncDef(func_def *FuncDef) { this.decl_type = FUNC_DEF this.func_def = func_def } func (this *Decl) DeclType() DeclType { return this.decl_type } func (this *Decl) StructDef() *StructDef { return this.struct_def } func (this *Decl) FuncDecl() *FuncDecl { return this.func_decl } func (this *Decl) FuncDef() *FuncDef { return this.func_def } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/decl/func_decl.go ================================================ package decl import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/param_list" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type FuncDecl struct { type_specifier *type_specifier.TypeSpecifier identifier *lexer.Token param_list *param_list.ParamList } func (this *FuncDecl) Init( type_specifier *type_specifier.TypeSpecifier, identifier *lexer.Token, param_list *param_list.ParamList, ) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } this.type_specifier = type_specifier this.identifier = identifier this.param_list = param_list } func (this *FuncDecl) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *FuncDecl) Identifier() *lexer.Token { return this.identifier } func (this *FuncDecl) ParamList() *param_list.ParamList { return this.param_list } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/decl/func_def.go ================================================ package decl import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/param_list" "uPIMulator/src/host/interpreter/parser/stmt" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type FuncDef struct { type_specifier *type_specifier.TypeSpecifier identifier *lexer.Token param_list *param_list.ParamList body *stmt.Stmt } func (this *FuncDef) Init( type_specifier *type_specifier.TypeSpecifier, identifier *lexer.Token, param_list *param_list.ParamList, body *stmt.Stmt, ) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } else if body.StmtType() != stmt.BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.type_specifier = type_specifier this.identifier = identifier this.param_list = param_list this.body = body } func (this *FuncDef) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *FuncDef) Identifier() *lexer.Token { return this.identifier } func (this *FuncDef) ParamList() *param_list.ParamList { return this.param_list } func (this *FuncDef) Body() *stmt.Stmt { return this.body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/decl/struct_def.go ================================================ package decl import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/stmt" ) type StructDef struct { identifier *lexer.Token body *stmt.Stmt } func (this *StructDef) Init(identifier *lexer.Token, body *stmt.Stmt) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } else if body.StmtType() != stmt.BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.identifier = identifier this.body = body } func (this *StructDef) Identifier() *lexer.Token { return this.identifier } func (this *StructDef) Body() *stmt.Stmt { return this.body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/directive/define_directive.go ================================================ package directive import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/expr" ) type DefineDirective struct { lvalue *lexer.Token rvalue *expr.Expr } func (this *DefineDirective) Init(lvalue *lexer.Token, rvalue *expr.Expr) { if lvalue.TokenType() != lexer.IDENTIFIER { err := errors.New("lvalue's token type is not identifier") panic(err) } this.lvalue = lvalue this.rvalue = rvalue } func (this *DefineDirective) Lvalue() *lexer.Token { return this.lvalue } func (this *DefineDirective) Rvalue() *expr.Expr { return this.rvalue } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/directive/directive.go ================================================ package directive type DirectiveType int const ( INCLUDE DirectiveType = iota DEFINE ) type Directive struct { directive_type DirectiveType include_directive *IncludeDirective define_directive *DefineDirective } func (this *Directive) InitIncludeDirective(include_directive *IncludeDirective) { this.directive_type = INCLUDE this.include_directive = include_directive } func (this *Directive) InitDefineDirective(define_directive *DefineDirective) { this.directive_type = DEFINE this.define_directive = define_directive } func (this *Directive) DirectiveType() DirectiveType { return this.directive_type } func (this *Directive) IncludeDirective() *IncludeDirective { return this.include_directive } func (this *Directive) DefineDirective() *DefineDirective { return this.define_directive } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/directive/include_directive.go ================================================ package directive import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type IncludeDirective struct { header *lexer.Token } func (this *IncludeDirective) Init(header *lexer.Token) { if header.TokenType() != lexer.HEADER { err := errors.New("header's token type is not header") panic(err) } this.header = header } func (this *IncludeDirective) Header() *lexer.Token { return this.header } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/additive_expr.go ================================================ package expr import ( "errors" ) type AdditiveExprType int const ( ADD AdditiveExprType = iota SUB ) type AdditiveExpr struct { additive_expr_type AdditiveExprType loperand *Expr roperand *Expr } func (this *AdditiveExpr) Init( additive_expr_type AdditiveExprType, loperand *Expr, roperand *Expr, ) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE { err := errors.New("roperand expr type is wrong") panic(err) } this.additive_expr_type = additive_expr_type this.loperand = loperand this.roperand = roperand } func (this *AdditiveExpr) AdditiveExprType() AdditiveExprType { return this.additive_expr_type } func (this *AdditiveExpr) Loperand() *Expr { return this.loperand } func (this *AdditiveExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/arg_list.go ================================================ package expr type ArgList struct { args []*Expr } func (this *ArgList) Init() { this.args = make([]*Expr, 0) } func (this *ArgList) Length() int { return len(this.args) } func (this *ArgList) Get(pos int) *Expr { return this.args[pos] } func (this *ArgList) Append(arg *Expr) { this.args = append(this.args, arg) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/assignment_expr.go ================================================ package expr import ( "errors" ) type AssignmentExprType int const ( ASSIGN AssignmentExprType = iota STAR_ASSIGN DIV_ASSIGN MOD_ASSIGN PLUS_ASSIGN MINUS_ASSIGN LSHIFT_ASSIGN RSHIFT_ASSIGN AND_ASSIGN CARET_ASSIGN OR_ASSIGN ) type AssignmentExpr struct { assignment_expr_type AssignmentExprType lvalue *Expr rvalue *Expr } func (this *AssignmentExpr) Init( assignment_expr_type AssignmentExprType, lvalue *Expr, rvalue *Expr, ) { if lvalue.ExprType() != PRIMARY && lvalue.ExprType() != POSTFIX && lvalue.ExprType() != UNARY { err := errors.New("lvalue expr type is wrong") panic(err) } else if rvalue.ExprType() != PRIMARY && rvalue.ExprType() != POSTFIX && rvalue.ExprType() != UNARY && rvalue.ExprType() != MULTIPLICATIVE && rvalue.ExprType() != ADDITIVE && rvalue.ExprType() != SHIFT && rvalue.ExprType() != RELATIONAL && rvalue.ExprType() != EQUALITY && rvalue.ExprType() != BITWISE_AND && rvalue.ExprType() != BITWISE_XOR && rvalue.ExprType() != BITWISE_OR && rvalue.ExprType() != LOGICAL_AND && rvalue.ExprType() != LOGICAL_OR && rvalue.ExprType() != CONDITIONAL { err := errors.New("rvalue expr type is wrong") panic(err) } this.assignment_expr_type = assignment_expr_type this.lvalue = lvalue this.rvalue = rvalue } func (this *AssignmentExpr) AssignmentExprType() AssignmentExprType { return this.assignment_expr_type } func (this *AssignmentExpr) Lvalue() *Expr { return this.lvalue } func (this *AssignmentExpr) Rvalue() *Expr { return this.rvalue } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/bitwise_and_expr.go ================================================ package expr import ( "errors" ) type BitwiseAndExpr struct { loperand *Expr roperand *Expr } func (this *BitwiseAndExpr) Init(loperand *Expr, roperand *Expr) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY && loperand.ExprType() != BITWISE_AND { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY && roperand.ExprType() != BITWISE_AND { err := errors.New("roperand expr type is wrong") panic(err) } this.loperand = loperand this.roperand = roperand } func (this *BitwiseAndExpr) Loperand() *Expr { return this.loperand } func (this *BitwiseAndExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/bitwise_or_expr.go ================================================ package expr import ( "errors" ) type BitwiseOrExpr struct { loperand *Expr roperand *Expr } func (this *BitwiseOrExpr) Init(loperand *Expr, roperand *Expr) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY && loperand.ExprType() != BITWISE_AND && loperand.ExprType() != BITWISE_XOR && loperand.ExprType() != BITWISE_OR { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY && roperand.ExprType() != BITWISE_AND && roperand.ExprType() != BITWISE_XOR && roperand.ExprType() != BITWISE_OR { err := errors.New("roperand expr type is wrong") panic(err) } this.loperand = loperand this.roperand = roperand } func (this *BitwiseOrExpr) Loperand() *Expr { return this.loperand } func (this *BitwiseOrExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/bitwise_xor_expr.go ================================================ package expr import ( "errors" ) type BitwiseXorExpr struct { loperand *Expr roperand *Expr } func (this *BitwiseXorExpr) Init(loperand *Expr, roperand *Expr) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY && loperand.ExprType() != BITWISE_AND && loperand.ExprType() != BITWISE_XOR { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY && roperand.ExprType() != BITWISE_AND && roperand.ExprType() != BITWISE_XOR { err := errors.New("roperand expr type is wrong") panic(err) } this.loperand = loperand this.roperand = roperand } func (this *BitwiseXorExpr) Loperand() *Expr { return this.loperand } func (this *BitwiseXorExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/conditional_expr.go ================================================ package expr import ( "errors" ) type ConditionalExpr struct { conditional_expr *Expr true_expr *Expr false_expr *Expr } func (this *ConditionalExpr) Init(conditional_expr *Expr, true_expr *Expr, false_expr *Expr) { if conditional_expr.ExprType() != PRIMARY && conditional_expr.ExprType() != POSTFIX && conditional_expr.ExprType() != UNARY && conditional_expr.ExprType() != MULTIPLICATIVE && conditional_expr.ExprType() != ADDITIVE && conditional_expr.ExprType() != SHIFT && conditional_expr.ExprType() != RELATIONAL && conditional_expr.ExprType() != EQUALITY && conditional_expr.ExprType() != BITWISE_AND && conditional_expr.ExprType() != BITWISE_XOR && conditional_expr.ExprType() != BITWISE_OR && conditional_expr.ExprType() != LOGICAL_AND && conditional_expr.ExprType() != LOGICAL_OR { err := errors.New("conditional_expr expr type is wrong") panic(err) } else if true_expr.ExprType() != PRIMARY && true_expr.ExprType() != POSTFIX && true_expr.ExprType() != UNARY && true_expr.ExprType() != MULTIPLICATIVE && true_expr.ExprType() != ADDITIVE && true_expr.ExprType() != SHIFT && true_expr.ExprType() != RELATIONAL && true_expr.ExprType() != EQUALITY && true_expr.ExprType() != BITWISE_AND && true_expr.ExprType() != BITWISE_XOR && true_expr.ExprType() != BITWISE_OR && true_expr.ExprType() != LOGICAL_AND && true_expr.ExprType() != LOGICAL_OR && true_expr.ExprType() != CONDITIONAL { err := errors.New("true_expr expr type is wrong") panic(err) } else if false_expr.ExprType() != PRIMARY && false_expr.ExprType() != POSTFIX && false_expr.ExprType() != UNARY && false_expr.ExprType() != MULTIPLICATIVE && false_expr.ExprType() != ADDITIVE && false_expr.ExprType() != SHIFT && false_expr.ExprType() != RELATIONAL && false_expr.ExprType() != EQUALITY && false_expr.ExprType() != BITWISE_AND && false_expr.ExprType() != BITWISE_XOR && false_expr.ExprType() != BITWISE_OR && false_expr.ExprType() != LOGICAL_AND && false_expr.ExprType() != LOGICAL_OR && false_expr.ExprType() != CONDITIONAL { err := errors.New("true_expr expr type is wrong") panic(err) } this.conditional_expr = conditional_expr this.true_expr = true_expr this.false_expr = false_expr } func (this *ConditionalExpr) ConditionalExpr() *Expr { return this.conditional_expr } func (this *ConditionalExpr) TrueExpr() *Expr { return this.true_expr } func (this *ConditionalExpr) FalseExpr() *Expr { return this.false_expr } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/equality_expr.go ================================================ package expr import ( "errors" ) type EqualityExprType int const ( EQ EqualityExprType = iota NOT_EQ ) type EqualityExpr struct { equality_expr_type EqualityExprType loperand *Expr roperand *Expr } func (this *EqualityExpr) Init( equality_expr_type EqualityExprType, loperand *Expr, roperand *Expr, ) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY { err := errors.New("roperand expr type is wrong") panic(err) } this.equality_expr_type = equality_expr_type this.loperand = loperand this.roperand = roperand } func (this *EqualityExpr) EqualityExprType() EqualityExprType { return this.equality_expr_type } func (this *EqualityExpr) Loperand() *Expr { return this.loperand } func (this *EqualityExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/expr.go ================================================ package expr type ExprType int const ( PRIMARY ExprType = iota POSTFIX UNARY MULTIPLICATIVE ADDITIVE SHIFT RELATIONAL EQUALITY BITWISE_AND BITWISE_XOR BITWISE_OR LOGICAL_AND LOGICAL_OR CONDITIONAL ASSIGNMENT ) type Expr struct { expr_type ExprType primary_expr *PrimaryExpr postfix_expr *PostfixExpr unary_expr *UnaryExpr multiplicative_expr *MultiplicativeExpr additive_expr *AdditiveExpr shift_expr *ShiftExpr relational_expr *RelationalExpr equality_expr *EqualityExpr bitwise_and_expr *BitwiseAndExpr bitwise_xor_expr *BitwiseXorExpr bitwise_or_expr *BitwiseOrExpr logical_and_expr *LogicalAndExpr logical_or_expr *LogicalOrExpr conditional_expr *ConditionalExpr assignment_expr *AssignmentExpr } func (this *Expr) InitPrimaryExpr(primary_expr *PrimaryExpr) { this.expr_type = PRIMARY this.primary_expr = primary_expr } func (this *Expr) InitPostfixExpr(postfix_expr *PostfixExpr) { this.expr_type = POSTFIX this.postfix_expr = postfix_expr } func (this *Expr) InitUnaryExpr(unary_expr *UnaryExpr) { this.expr_type = UNARY this.unary_expr = unary_expr } func (this *Expr) InitMultiplicativeExpr(multiplicative_expr *MultiplicativeExpr) { this.expr_type = MULTIPLICATIVE this.multiplicative_expr = multiplicative_expr } func (this *Expr) InitAdditiveExpr(additive_expr *AdditiveExpr) { this.expr_type = ADDITIVE this.additive_expr = additive_expr } func (this *Expr) InitShiftExpr(shift_expr *ShiftExpr) { this.expr_type = SHIFT this.shift_expr = shift_expr } func (this *Expr) InitRelationalExpr(relational_expr *RelationalExpr) { this.expr_type = RELATIONAL this.relational_expr = relational_expr } func (this *Expr) InitEqualityExpr(equality_expr *EqualityExpr) { this.expr_type = EQUALITY this.equality_expr = equality_expr } func (this *Expr) InitBitwiseAndExpr(bitwise_and_expr *BitwiseAndExpr) { this.expr_type = BITWISE_AND this.bitwise_and_expr = bitwise_and_expr } func (this *Expr) InitBitwiseXorExpr(bitwise_xor_expr *BitwiseXorExpr) { this.expr_type = BITWISE_XOR this.bitwise_xor_expr = bitwise_xor_expr } func (this *Expr) InitBitwiseOrExpr(bitwise_or_expr *BitwiseOrExpr) { this.expr_type = BITWISE_OR this.bitwise_or_expr = bitwise_or_expr } func (this *Expr) InitLogicalAndExpr(logical_and_expr *LogicalAndExpr) { this.expr_type = LOGICAL_AND this.logical_and_expr = logical_and_expr } func (this *Expr) InitLogicalOrExpr(logical_or_expr *LogicalOrExpr) { this.expr_type = LOGICAL_OR this.logical_or_expr = logical_or_expr } func (this *Expr) InitConditionalExpr(conditional_expr *ConditionalExpr) { this.expr_type = CONDITIONAL this.conditional_expr = conditional_expr } func (this *Expr) InitAssignmentExpr(assignment_expr *AssignmentExpr) { this.expr_type = ASSIGNMENT this.assignment_expr = assignment_expr } func (this *Expr) ExprType() ExprType { return this.expr_type } func (this *Expr) PrimaryExpr() *PrimaryExpr { return this.primary_expr } func (this *Expr) PostfixExpr() *PostfixExpr { return this.postfix_expr } func (this *Expr) UnaryExpr() *UnaryExpr { return this.unary_expr } func (this *Expr) MultiplicativeExpr() *MultiplicativeExpr { return this.multiplicative_expr } func (this *Expr) AdditiveExpr() *AdditiveExpr { return this.additive_expr } func (this *Expr) ShiftExpr() *ShiftExpr { return this.shift_expr } func (this *Expr) RelationalExpr() *RelationalExpr { return this.relational_expr } func (this *Expr) BitwiseAndExpr() *BitwiseAndExpr { return this.bitwise_and_expr } func (this *Expr) BitwiseXorExpr() *BitwiseXorExpr { return this.bitwise_xor_expr } func (this *Expr) BitwiseOrExpr() *BitwiseOrExpr { return this.bitwise_or_expr } func (this *Expr) LogicalAndExpr() *LogicalAndExpr { return this.logical_and_expr } func (this *Expr) LogicalOrExpr() *LogicalOrExpr { return this.logical_or_expr } func (this *Expr) EqualityExpr() *EqualityExpr { return this.equality_expr } func (this *Expr) ConditionalExpr() *ConditionalExpr { return this.conditional_expr } func (this *Expr) AssignmentExpr() *AssignmentExpr { return this.assignment_expr } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/logical_and_expr.go ================================================ package expr import ( "errors" ) type LogicalAndExpr struct { loperand *Expr roperand *Expr } func (this *LogicalAndExpr) Init(loperand *Expr, roperand *Expr) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY && loperand.ExprType() != BITWISE_AND && loperand.ExprType() != BITWISE_XOR && loperand.ExprType() != BITWISE_OR && loperand.ExprType() != LOGICAL_AND { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY && roperand.ExprType() != BITWISE_AND && roperand.ExprType() != BITWISE_XOR && roperand.ExprType() != BITWISE_OR && roperand.ExprType() != LOGICAL_AND { err := errors.New("roperand expr type is wrong") panic(err) } this.loperand = loperand this.roperand = roperand } func (this *LogicalAndExpr) Loperand() *Expr { return this.loperand } func (this *LogicalAndExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/logical_or_expr.go ================================================ package expr import ( "errors" ) type LogicalOrExpr struct { loperand *Expr roperand *Expr } func (this *LogicalOrExpr) Init(loperand *Expr, roperand *Expr) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL && loperand.ExprType() != EQUALITY && loperand.ExprType() != BITWISE_AND && loperand.ExprType() != BITWISE_XOR && loperand.ExprType() != BITWISE_OR && loperand.ExprType() != LOGICAL_AND && loperand.ExprType() != LOGICAL_OR { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL && roperand.ExprType() != EQUALITY && roperand.ExprType() != BITWISE_AND && roperand.ExprType() != BITWISE_XOR && roperand.ExprType() != BITWISE_OR && roperand.ExprType() != LOGICAL_AND && roperand.ExprType() != LOGICAL_OR { err := errors.New("roperand expr type is wrong") panic(err) } this.loperand = loperand this.roperand = roperand } func (this *LogicalOrExpr) Loperand() *Expr { return this.loperand } func (this *LogicalOrExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/multiplicative_expr.go ================================================ package expr import ( "errors" ) type MultiplicativeExprType int const ( MUL MultiplicativeExprType = iota DIV MOD ) type MultiplicativeExpr struct { multiplicative_expr_type MultiplicativeExprType loperand *Expr roperand *Expr } func (this *MultiplicativeExpr) Init( multiplicative_expr_type MultiplicativeExprType, loperand *Expr, roperand *Expr, ) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE { err := errors.New("roperand expr type is wrong") panic(err) } this.multiplicative_expr_type = multiplicative_expr_type this.loperand = loperand this.roperand = roperand } func (this *MultiplicativeExpr) MultiplicativeExprType() MultiplicativeExprType { return this.multiplicative_expr_type } func (this *MultiplicativeExpr) Loperand() *Expr { return this.loperand } func (this *MultiplicativeExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/postfix_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type PostfixExprType int const ( BRACKET PostfixExprType = iota CALL DOT ARROW POSTFIX_PLUS_PLUS POSTFIX_MINUS_MINUS ) type PostfixExpr struct { postfix_expr_type PostfixExprType base *Expr offset_expr *Expr arg_list *ArgList offset_token *lexer.Token } func (this *PostfixExpr) InitBracket(base *Expr, offset_expr *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } this.postfix_expr_type = BRACKET this.base = base this.offset_expr = offset_expr } func (this *PostfixExpr) InitCall(base *Expr, arg_list *ArgList) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } this.postfix_expr_type = CALL this.base = base this.arg_list = arg_list } func (this *PostfixExpr) InitDot(base *Expr, offset_token *lexer.Token) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } else if offset_token.TokenType() != lexer.IDENTIFIER { err := errors.New("offset token's token type is not identifier") panic(err) } this.postfix_expr_type = DOT this.base = base this.offset_token = offset_token } func (this *PostfixExpr) InitArrow(base *Expr, offset_token *lexer.Token) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } else if offset_token.TokenType() != lexer.IDENTIFIER { err := errors.New("offset token's token type is not identifier") panic(err) } this.postfix_expr_type = ARROW this.base = base this.offset_token = offset_token } func (this *PostfixExpr) InitPlusPlus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } this.postfix_expr_type = POSTFIX_PLUS_PLUS this.base = base } func (this *PostfixExpr) InitMinusMinus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX { err := errors.New("base expr type is wrong") panic(err) } this.postfix_expr_type = POSTFIX_MINUS_MINUS this.base = base } func (this *PostfixExpr) PostfixExprType() PostfixExprType { return this.postfix_expr_type } func (this *PostfixExpr) Base() *Expr { return this.base } func (this *PostfixExpr) OffsetExpr() *Expr { return this.offset_expr } func (this *PostfixExpr) ArgList() *ArgList { return this.arg_list } func (this *PostfixExpr) OffsetToken() *lexer.Token { return this.offset_token } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/primary_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type PrimaryExprType int const ( IDENTIFIER PrimaryExprType = iota NUMBER STRING NULLPTR PAREN ) type PrimaryExpr struct { primary_expr_type PrimaryExprType token *lexer.Token expr *Expr } func (this *PrimaryExpr) InitIdentifier(token *lexer.Token) { this.primary_expr_type = IDENTIFIER this.token = token this.expr = nil } func (this *PrimaryExpr) InitNumber(token *lexer.Token) { this.primary_expr_type = NUMBER this.token = token this.expr = nil } func (this *PrimaryExpr) InitString(token *lexer.Token) { this.primary_expr_type = STRING this.token = token this.expr = nil } func (this *PrimaryExpr) InitNullptr(token *lexer.Token) { this.primary_expr_type = NULLPTR this.token = token this.expr = nil } func (this *PrimaryExpr) InitParen(expr *Expr) { this.primary_expr_type = PAREN this.token = nil this.expr = expr } func (this *PrimaryExpr) PrimaryExprType() PrimaryExprType { return this.primary_expr_type } func (this *PrimaryExpr) Token() *lexer.Token { if this.token == nil { err := errors.New("token == nil") panic(err) } return this.token } func (this *PrimaryExpr) Expr() *Expr { if this.expr == nil { err := errors.New("expr == nil") panic(err) } return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/relational_expr.go ================================================ package expr import ( "errors" ) type RelationalExprType int const ( LESS RelationalExprType = iota LESS_EQ GREATER GREATER_EQ ) type RelationalExpr struct { relational_expr_type RelationalExprType loperand *Expr roperand *Expr } func (this *RelationalExpr) Init( relational_expr_type RelationalExprType, loperand *Expr, roperand *Expr, ) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT && loperand.ExprType() != RELATIONAL { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT && roperand.ExprType() != RELATIONAL { err := errors.New("roperand expr type is wrong") panic(err) } this.relational_expr_type = relational_expr_type this.loperand = loperand this.roperand = roperand } func (this *RelationalExpr) RelationalExprType() RelationalExprType { return this.relational_expr_type } func (this *RelationalExpr) Loperand() *Expr { return this.loperand } func (this *RelationalExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/shift_expr.go ================================================ package expr import ( "errors" ) type ShiftExprType int const ( LSHIFT ShiftExprType = iota RSHIFT ) type ShiftExpr struct { shift_expr_type ShiftExprType loperand *Expr roperand *Expr } func (this *ShiftExpr) Init( shift_expr_type ShiftExprType, loperand *Expr, roperand *Expr, ) { if loperand.ExprType() != PRIMARY && loperand.ExprType() != POSTFIX && loperand.ExprType() != UNARY && loperand.ExprType() != MULTIPLICATIVE && loperand.ExprType() != ADDITIVE && loperand.ExprType() != SHIFT { err := errors.New("loperand expr type is wrong") panic(err) } else if roperand.ExprType() != PRIMARY && roperand.ExprType() != POSTFIX && roperand.ExprType() != UNARY && roperand.ExprType() != MULTIPLICATIVE && roperand.ExprType() != ADDITIVE && roperand.ExprType() != SHIFT { err := errors.New("roperand expr type is wrong") panic(err) } this.shift_expr_type = shift_expr_type this.loperand = loperand this.roperand = roperand } func (this *ShiftExpr) ShiftExprType() ShiftExprType { return this.shift_expr_type } func (this *ShiftExpr) Loperand() *Expr { return this.loperand } func (this *ShiftExpr) Roperand() *Expr { return this.roperand } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/expr/unary_expr.go ================================================ package expr import ( "errors" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type UnaryExprType int const ( UNARY_PLUS_PLUS UnaryExprType = iota UNARY_MINUS_MINUS AND STAR PLUS MINUS TILDE NOT SIZEOF ) type UnaryExpr struct { unary_expr_type UnaryExprType base *Expr type_specifier *type_specifier.TypeSpecifier } func (this *UnaryExpr) InitPlusPlus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = UNARY_PLUS_PLUS this.base = base } func (this *UnaryExpr) InitMinusMinus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = UNARY_MINUS_MINUS this.base = base } func (this *UnaryExpr) InitAnd(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = AND this.base = base } func (this *UnaryExpr) InitStar(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = STAR this.base = base } func (this *UnaryExpr) InitPlus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = PLUS this.base = base } func (this *UnaryExpr) InitMinus(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = MINUS this.base = base } func (this *UnaryExpr) InitTilde(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = TILDE this.base = base } func (this *UnaryExpr) InitNot(base *Expr) { if base.ExprType() != PRIMARY && base.ExprType() != POSTFIX && base.ExprType() != UNARY { err := errors.New("base expr type is wrong") panic(err) } this.unary_expr_type = NOT this.base = base } func (this *UnaryExpr) InitSizeof(type_specifier *type_specifier.TypeSpecifier) { this.unary_expr_type = SIZEOF this.type_specifier = type_specifier } func (this *UnaryExpr) UnaryExprType() UnaryExprType { return this.unary_expr_type } func (this *UnaryExpr) Base() *Expr { return this.base } func (this *UnaryExpr) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/param_list/param.go ================================================ package param_list import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type Param struct { type_specifier *type_specifier.TypeSpecifier identifier *lexer.Token } func (this *Param) Init(type_specifier *type_specifier.TypeSpecifier, identifier *lexer.Token) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } this.type_specifier = type_specifier this.identifier = identifier } func (this *Param) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *Param) Identifier() *lexer.Token { return this.identifier } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/param_list/param_list.go ================================================ package param_list type ParamList struct { params []*Param } func (this *ParamList) Init() { this.params = make([]*Param, 0) } func (this *ParamList) Length() int { return len(this.params) } func (this *ParamList) Get(pos int) *Param { return this.params[pos] } func (this *ParamList) Append(param *Param) { this.params = append(this.params, param) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/parser.go ================================================ package parser import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/decl" "uPIMulator/src/host/interpreter/parser/directive" "uPIMulator/src/host/interpreter/parser/expr" "uPIMulator/src/host/interpreter/parser/param_list" "uPIMulator/src/host/interpreter/parser/stmt" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type Parser struct { stack *Stack table *Table } func (this *Parser) Init() { this.stack = new(Stack) this.stack.Init() this.table = new(Table) this.table.Init(this.stack) this.RegisterTypeSpecifierVoid() this.RegisterTypeSpecifierChar() this.RegisterTypeSpecifierShort() this.RegisterTypeSpecifierInt() this.RegisterTypeSpecifierLong() this.RegisterTypeSpecifierStruct() this.RegisterTypeSpecifierStar() this.RegisterParamListBegin() this.RegisterParamListAppend() this.RegisterArgListBegin() this.RegisterArgListAppend() this.RegisterPrimaryExprIdentifier() this.RegisterPrimaryExprNumber() this.RegisterPrimaryExprString() this.RegisterPrimaryExprNullptr() this.RegisterPrimaryExprParen() this.RegisterPostfixExprBracket() this.RegisterPostfixExprCallEmpty() this.RegisterPostfixExprCallSingle() this.RegisterPostfixExprCallMultiple() this.RegisterPostfixExprDot() this.RegisterPostfixExprArrow() this.RegisterPostfixExprPlusPlus() this.RegisterPostfixExprMinusMinus() this.RegisterUnaryExprPlusPlus() this.RegisterUnaryExprMinusMinus() this.RegisterUnaryExprAnd() this.RegisterUnaryExprStar() this.RegisterUnaryExprPlus() this.RegisterUnaryExprMinus() this.RegisterUnaryExprTilde() this.RegisterUnaryExprNot() this.RegisterUnaryExprSizeof() this.RegisterMultiplicativeExprMul() this.RegisterMultiplicativeExprDiv() this.RegisterMultiplicativeExprMod() this.RegisterAdditiveExprAdd() this.RegisterAdditiveExprSub() this.RegisterShiftExprLshift() this.RegisterShiftExprRshift() this.RegisterRelationalExprLess() this.RegisterRelationalExprLessEq() this.RegisterRelationalExprGreater() this.RegisterRelationalExprGreaterEq() this.RegisterEqualityExprEq() this.RegisterEqualityExprNotEq() this.RegisterBitwiseAndExpr() this.RegisterBitwiseXorExpr() this.RegisterBitwiseOrExpr() this.RegisterLogicalAndExpr() this.RegisterLogicalOrExpr() this.RegisterConditionalExpr() this.RegisterAssignmentExprAssign() this.RegisterAssignmentExprStarAssign() this.RegisterAssignmentExprDivAssign() this.RegisterAssignmentExprModAssign() this.RegisterAssignmentExprPlusAssign() this.RegisterAssignmentExprMinusAssign() this.RegisterAssignmentExprLshiftAssign() this.RegisterAssignmentExprRshiftAssign() this.RegisterAssignmentExprAndAssign() this.RegisterAssignmentExprCaretAssign() this.RegisterAssignmentExprOrAssign() this.RegisterConcatExpr() this.RegisterEmptyStmt() this.RegisterVarDeclStmt() this.RegisterVarDeclInitStmt() this.RegisterForStmt() this.RegisterDpuForeachStmt() this.RegisterWhileStmt() this.RegisterContinueStmt() this.RegisterBreakStmt() this.RegisterIfStmt() this.RegisterElseIfStmt() this.RegisterElseStmt() this.RegisterReturnStmtWithoutValue() this.RegisterReturnStmtWithValue() this.RegisterExprStmt() this.RegisterBlockStmt() this.RegisterStructDef() this.RegisterFuncDeclEmpty() this.RegisterFuncDeclNonEmpty() this.RegisterFuncDefEmpty() this.RegisterFuncDefNonEmpty() this.RegisterIncludeDirective() this.RegisterDefineDirective() } func (this *Parser) Parse(token_stream *lexer.TokenStream) *Ast { for i := 0; i < token_stream.Length(); i++ { token := token_stream.Get(i) for this.table.IsReducible(token) { this.table.Reduce(token) } stack_item := new(StackItem) stack_item.InitToken(token) this.stack.Push(stack_item) } return this.stack.Accept() } func (this *Parser) RegisterTypeSpecifierVoid() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.VOID { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitPrimitive(type_specifier.VOID) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierChar() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CHAR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitPrimitive(type_specifier.CHAR) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierShort() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SHORT { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitPrimitive(type_specifier.SHORT) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierInt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.INT { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitPrimitive(type_specifier.INT) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierLong() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LONG { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitPrimitive(type_specifier.LONG) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierStruct() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.STRUCT && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { struct_identifier := stack_items[1].Expr().PrimaryExpr().Token() type_specifier_ := new(type_specifier.TypeSpecifier) type_specifier_.InitStruct(type_specifier.STRUCT, struct_identifier) stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterTypeSpecifierStar() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TYPE_SPECIFIER && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STAR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := stack_items[0].TypeSpecifier() type_specifier_.AddStar() stack_item := new(StackItem) stack_item.InitTypeSpecifier(type_specifier_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterParamListBegin() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TYPE_SPECIFIER && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := stack_items[0].TypeSpecifier() identifier := stack_items[1].Expr().PrimaryExpr().Token() param := new(param_list.Param) param.Init(type_specifier_, identifier) param_list_ := new(param_list.ParamList) param_list_.Init() param_list_.Append(param) stack_item := new(StackItem) stack_item.InitParamList(param_list_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterParamListAppend() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.COMMA && stack_items[2].StackItemType() == TYPE_SPECIFIER && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PRIMARY && stack_items[3].Expr().PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param_list_ := stack_items[0].ParamList() type_specifier_ := stack_items[2].TypeSpecifier() identifier := stack_items[3].Expr().PrimaryExpr().Token() param := new(param_list.Param) param.Init(type_specifier_, identifier) param_list_.Append(param) stack_item := new(StackItem) stack_item.InitParamList(param_list_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterArgListBegin() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, lexer.ASSIGN: true, lexer.STAR_ASSIGN: true, lexer.DIV_ASSIGN: true, lexer.MOD_ASSIGN: true, lexer.PLUS_ASSIGN: true, lexer.MINUS_ASSIGN: true, lexer.LSHIFT_ASSIGN: true, lexer.RSHIFT_ASSIGN: true, lexer.AND_ASSIGN: true, lexer.CARET_ASSIGN: true, lexer.OR_ASSIGN: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.COMMA && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { arg1 := stack_items[0].Expr() arg2 := stack_items[2].Expr() arg_list := new(expr.ArgList) arg_list.Init() arg_list.Append(arg1) arg_list.Append(arg2) stack_item := new(StackItem) stack_item.InitArgList(arg_list) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterArgListAppend() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, lexer.ASSIGN: true, lexer.STAR_ASSIGN: true, lexer.DIV_ASSIGN: true, lexer.MOD_ASSIGN: true, lexer.PLUS_ASSIGN: true, lexer.MINUS_ASSIGN: true, lexer.LSHIFT_ASSIGN: true, lexer.RSHIFT_ASSIGN: true, lexer.AND_ASSIGN: true, lexer.CARET_ASSIGN: true, lexer.OR_ASSIGN: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == ARG_LIST && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.COMMA && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { arg_list := stack_items[0].ArgList() arg := stack_items[2].Expr() arg_list.Append(arg) stack_item := new(StackItem) stack_item.InitArgList(arg_list) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPrimaryExprIdentifier() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.PrimaryExpr) primary_expr.InitIdentifier(token) expr_ := new(expr.Expr) expr_.InitPrimaryExpr(primary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPrimaryExprNumber() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.NUMBER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.PrimaryExpr) primary_expr.InitNumber(token) expr_ := new(expr.Expr) expr_.InitPrimaryExpr(primary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPrimaryExprString() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.STRING { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.PrimaryExpr) primary_expr.InitString(token) expr_ := new(expr.Expr) expr_.InitPrimaryExpr(primary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPrimaryExprNullptr() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.NULL { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { token := stack_items[0].Token() primary_expr := new(expr.PrimaryExpr) primary_expr.InitNullptr(token) expr_ := new(expr.Expr) expr_.InitPrimaryExpr(primary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPrimaryExprParen() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LPAREN && stack_items[1].StackItemType() == EXPR && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.RPAREN { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { e := stack_items[1].Expr() primary_expr := new(expr.PrimaryExpr) primary_expr.InitParen(e) expr_ := new(expr.Expr) expr_.InitPrimaryExpr(primary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprBracket() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LBRACKET && stack_items[2].StackItemType() == EXPR && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.RBRACKET { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() offset_expr := stack_items[2].Expr() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitBracket(base, offset_expr) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprCallEmpty() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.RPAREN { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() arg_list := new(expr.ArgList) arg_list.Init() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitCall(base, arg_list) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprCallSingle() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.PAREN { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() arg_list := new(expr.ArgList) arg_list.Init() arg_list.Append(stack_items[1].Expr().PrimaryExpr().Expr()) postfix_expr := new(expr.PostfixExpr) postfix_expr.InitCall(base, arg_list) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprCallMultiple() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == ARG_LIST && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.RPAREN { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() arg_list := stack_items[2].ArgList() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitCall(base, arg_list) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprDot() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.DOT && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() offset_token := stack_items[2].Token() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitDot(base, offset_token) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprArrow() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.ARROW && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.IDENTIFIER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() offset_token := stack_items[2].Token() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitArrow(base, offset_token) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprPlusPlus() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PLUS_PLUS { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitPlusPlus(base) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterPostfixExprMinusMinus() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MINUS_MINUS { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[0].Expr() postfix_expr := new(expr.PostfixExpr) postfix_expr.InitMinusMinus(base) expr_ := new(expr.Expr) expr_.InitPostfixExpr(postfix_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprPlusPlus() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.PLUS_PLUS && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitPlusPlus(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprMinusMinus() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.MINUS_MINUS && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitMinusMinus(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprAnd() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.AND && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitAnd(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprStar() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.STAR && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitStar(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprPlus() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.PLUS && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitPlus(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprMinus() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.MINUS && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitMinus(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprTilde() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.TILDE && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitTilde(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprNot() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.NOT && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { base := stack_items[1].Expr() unary_expr := new(expr.UnaryExpr) unary_expr.InitNot(base) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterUnaryExprSizeof() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SIZEOF && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == TYPE_SPECIFIER && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.RPAREN { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := stack_items[2].TypeSpecifier() unary_expr := new(expr.UnaryExpr) unary_expr.InitSizeof(type_specifier_) expr_ := new(expr.Expr) expr_.InitUnaryExpr(unary_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterMultiplicativeExprMul() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STAR && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() multiplicative_expr := new(expr.MultiplicativeExpr) multiplicative_expr.Init(expr.MUL, loperand, roperand) expr_ := new(expr.Expr) expr_.InitMultiplicativeExpr(multiplicative_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterMultiplicativeExprDiv() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.DIV && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() multiplicative_expr := new(expr.MultiplicativeExpr) multiplicative_expr.Init(expr.DIV, loperand, roperand) expr_ := new(expr.Expr) expr_.InitMultiplicativeExpr(multiplicative_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterMultiplicativeExprMod() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MOD && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() multiplicative_expr := new(expr.MultiplicativeExpr) multiplicative_expr.Init(expr.MOD, loperand, roperand) expr_ := new(expr.Expr) expr_.InitMultiplicativeExpr(multiplicative_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAdditiveExprAdd() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PLUS && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() additive_expr := new(expr.AdditiveExpr) additive_expr.Init(expr.ADD, loperand, roperand) expr_ := new(expr.Expr) expr_.InitAdditiveExpr(additive_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAdditiveExprSub() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MINUS && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() additive_expr := new(expr.AdditiveExpr) additive_expr.Init(expr.SUB, loperand, roperand) expr_ := new(expr.Expr) expr_.InitAdditiveExpr(additive_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterShiftExprLshift() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LSHIFT && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() shift_expr := new(expr.ShiftExpr) shift_expr.Init(expr.LSHIFT, loperand, roperand) expr_ := new(expr.Expr) expr_.InitShiftExpr(shift_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterShiftExprRshift() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.RSHIFT && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() shift_expr := new(expr.ShiftExpr) shift_expr.Init(expr.RSHIFT, loperand, roperand) expr_ := new(expr.Expr) expr_.InitShiftExpr(shift_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterRelationalExprLess() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LESS && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() relational_expr := new(expr.RelationalExpr) relational_expr.Init(expr.LESS, loperand, roperand) expr_ := new(expr.Expr) expr_.InitRelationalExpr(relational_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterRelationalExprLessEq() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LESS_EQ && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() relational_expr := new(expr.RelationalExpr) relational_expr.Init(expr.LESS_EQ, loperand, roperand) expr_ := new(expr.Expr) expr_.InitRelationalExpr(relational_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterRelationalExprGreater() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.GREATER && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() relational_expr := new(expr.RelationalExpr) relational_expr.Init(expr.GREATER, loperand, roperand) expr_ := new(expr.Expr) expr_.InitRelationalExpr(relational_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterRelationalExprGreaterEq() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.GREATER_EQ && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() relational_expr := new(expr.RelationalExpr) relational_expr.Init(expr.GREATER_EQ, loperand, roperand) expr_ := new(expr.Expr) expr_.InitRelationalExpr(relational_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterEqualityExprEq() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.EQ && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() equality_expr := new(expr.EqualityExpr) equality_expr.Init(expr.EQ, loperand, roperand) expr_ := new(expr.Expr) expr_.InitEqualityExpr(equality_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterEqualityExprNotEq() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.NOT_EQ && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() equality_expr := new(expr.EqualityExpr) equality_expr.Init(expr.NOT_EQ, loperand, roperand) expr_ := new(expr.Expr) expr_.InitEqualityExpr(equality_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterBitwiseAndExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.AND && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() bitwise_and_expr := new(expr.BitwiseAndExpr) bitwise_and_expr.Init(loperand, roperand) expr_ := new(expr.Expr) expr_.InitBitwiseAndExpr(bitwise_and_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterBitwiseXorExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.CARET && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() bitwise_xor_expr := new(expr.BitwiseXorExpr) bitwise_xor_expr.Init(loperand, roperand) expr_ := new(expr.Expr) expr_.InitBitwiseXorExpr(bitwise_xor_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterBitwiseOrExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.OR && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() bitwise_or_expr := new(expr.BitwiseOrExpr) bitwise_or_expr.Init(loperand, roperand) expr_ := new(expr.Expr) expr_.InitBitwiseOrExpr(bitwise_or_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterLogicalAndExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.AND_AND && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() logical_and_expr := new(expr.LogicalAndExpr) logical_and_expr.Init(loperand, roperand) expr_ := new(expr.Expr) expr_.InitLogicalAndExpr(logical_and_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterLogicalOrExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.OR_OR && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { loperand := stack_items[0].Expr() roperand := stack_items[2].Expr() logical_or_expr := new(expr.LogicalOrExpr) logical_or_expr.Init(loperand, roperand) expr_ := new(expr.Expr) expr_.InitLogicalOrExpr(logical_or_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterConditionalExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.QUESTION && stack_items[2].StackItemType() == EXPR && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.COLON && stack_items[4].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { condition_expr := stack_items[0].Expr() true_expr := stack_items[2].Expr() false_expr := stack_items[4].Expr() conditional_expr := new(expr.ConditionalExpr) conditional_expr.Init(condition_expr, true_expr, false_expr) expr_ := new(expr.Expr) expr_.InitConditionalExpr(conditional_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprStarAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.STAR_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.STAR_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprDivAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.DIV_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.DIV_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprModAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MOD_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.MOD_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprPlusAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.PLUS_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.PLUS_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprMinusAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.MINUS_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.MINUS_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprLshiftAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LSHIFT_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.LSHIFT_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprRshiftAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.RSHIFT_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.RSHIFT_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprAndAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.AND_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.AND_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprCaretAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.CARET_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.CARET_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterAssignmentExprOrAssign() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, lexer.PLUS: true, lexer.MINUS: true, lexer.LSHIFT: true, lexer.RSHIFT: true, lexer.LESS: true, lexer.LESS_EQ: true, lexer.GREATER: true, lexer.GREATER_EQ: true, lexer.EQ: true, lexer.NOT_EQ: true, lexer.AND: true, lexer.CARET: true, lexer.OR: true, lexer.AND_AND: true, lexer.OR_OR: true, lexer.QUESTION: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.OR_ASSIGN && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[2].Expr() assignment_expr := new(expr.AssignmentExpr) assignment_expr.Init(expr.OR_ASSIGN, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAssignmentExpr(assignment_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterConcatExpr() { precedence := map[lexer.TokenType]bool{ lexer.LBRACKET: true, lexer.LPAREN: true, lexer.DOT: true, lexer.ARROW: true, lexer.PLUS_PLUS: true, lexer.MINUS_MINUS: true, lexer.STAR: true, lexer.DIV: true, lexer.MOD: true, } reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[0].Expr() rvalue := stack_items[1].Expr() additive_expr := new(expr.AdditiveExpr) additive_expr.Init(expr.ADD, lvalue, rvalue) expr_ := new(expr.Expr) expr_.InitAdditiveExpr(additive_expr) stack_item := new(StackItem) stack_item.InitExpr(expr_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterEmptyStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 1 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { empty_stmt := new(stmt.EmptyStmt) empty_stmt.Init() stmt_ := new(stmt.Stmt) stmt_.InitEmptyStmt(empty_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterVarDeclStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() var_decl_stmt := new(stmt.VarDeclStmt) var_decl_stmt.Init(type_specifier_, identifier) stmt_ := new(stmt.Stmt) stmt_.InitVarDeclStmt(var_decl_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterVarDeclInitStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.ASSIGN && stack_items[2].StackItemType() == EXPR && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) rvalue := stack_items[2].Expr() type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() var_decl_init_stmt := new(stmt.VarDeclInitStmt) var_decl_init_stmt.Init(type_specifier_, identifier, rvalue) stmt_ := new(stmt.Stmt) stmt_.InitVarDeclInitStmt(var_decl_init_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterForStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 7 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.FOR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == STMT && stack_items[3].StackItemType() == STMT && stack_items[4].StackItemType() == EXPR && stack_items[5].StackItemType() == TOKEN && stack_items[5].Token().TokenType() == lexer.RPAREN && stack_items[6].StackItemType() == STMT && stack_items[6].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { initialization := stack_items[2].Stmt() condition_stmt := stack_items[3].Stmt() update_expr := stack_items[4].Expr() body := stack_items[6].Stmt() if condition_stmt.StmtType() != stmt.EXPR { err := errors.New("condition stmt type is not expr") panic(err) } condition_expr := condition_stmt.ExprStmt().Expr() u := new(stmt.ExprStmt) u.Init(update_expr) update_stmt := new(stmt.Stmt) update_stmt.InitExprStmt(u) for_stmt := new(stmt.ForStmt) for_stmt.Init(initialization, condition_expr, update_stmt, body) stmt_ := new(stmt.Stmt) stmt_.InitForStmt(for_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterDpuForeachStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[0].Expr().ExprType() == expr.POSTFIX && stack_items[0].Expr().PostfixExpr().PostfixExprType() == expr.CALL && stack_items[0].Expr().PostfixExpr().Base().ExprType() == expr.PRIMARY && stack_items[0].Expr().PostfixExpr().Base().PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER && stack_items[0].Expr().PostfixExpr().Base().PrimaryExpr().Token().Attribute() == "DPU_FOREACH" && stack_items[0].Expr().PostfixExpr().ArgList().Length() == 3 && stack_items[1].StackItemType() == STMT && stack_items[1].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { foreach := stack_items[0].Expr().PostfixExpr().ArgList() body := stack_items[1].Stmt() dpu_foreach_stmt := new(stmt.DpuForeachStmt) dpu_foreach_stmt.Init(foreach, body) stmt_ := new(stmt.Stmt) stmt_.InitDpuForeachStmt(dpu_foreach_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterWhileStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.WHILE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.PAREN && stack_items[2].StackItemType() == STMT && stack_items[2].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { condition := stack_items[1].Expr().PrimaryExpr().Expr() body := stack_items[2].Stmt() while_stmt := new(stmt.WhileStmt) while_stmt.Init(condition, body) stmt_ := new(stmt.Stmt) stmt_.InitWhileStmt(while_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterContinueStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.CONTINUE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { continue_stmt := new(stmt.ContinueStmt) continue_stmt.Init() stmt_ := new(stmt.Stmt) stmt_.InitContinueStmt(continue_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterBreakStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.BREAK && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { break_stmt := new(stmt.BreakStmt) break_stmt.Init() stmt_ := new(stmt.Stmt) stmt_.InitBreakStmt(break_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterIfStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.IF && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.PAREN && stack_items[2].StackItemType() == STMT && stack_items[2].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { condition := stack_items[1].Expr().PrimaryExpr().Expr() body := stack_items[2].Stmt() if_stmt := new(stmt.IfStmt) if_stmt.Init(condition, body) stmt_ := new(stmt.Stmt) stmt_.InitIfStmt(if_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterElseIfStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == STMT && stack_items[0].Stmt().StmtType() == stmt.IF && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.ELSE && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.IF && stack_items[3].StackItemType() == EXPR && stack_items[3].Expr().ExprType() == expr.PRIMARY && stack_items[3].Expr().PrimaryExpr().PrimaryExprType() == expr.PAREN && stack_items[4].StackItemType() == STMT && stack_items[4].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { if_stmt := stack_items[0].Stmt().IfStmt() condition := stack_items[3].Expr().PrimaryExpr().Expr() body := stack_items[4].Stmt() if_stmt.AppendElseIf(condition, body) stmt_ := new(stmt.Stmt) stmt_.InitIfStmt(if_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterElseStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == STMT && stack_items[0].Stmt().StmtType() == stmt.IF && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.ELSE && stack_items[2].StackItemType() == STMT && stack_items[2].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { if_stmt := stack_items[0].Stmt().IfStmt() body := stack_items[2].Stmt() if_stmt.SetElseBody(body) stmt_ := new(stmt.Stmt) stmt_.InitIfStmt(if_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterReturnStmtWithoutValue() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.RETURN && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { return_stmt := new(stmt.ReturnStmt) return_stmt.InitWithoutValue() stmt_ := new(stmt.Stmt) stmt_.InitReturnStmt(return_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterReturnStmtWithValue() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.RETURN && stack_items[1].StackItemType() == EXPR && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { value := stack_items[1].Expr() return_stmt := new(stmt.ReturnStmt) return_stmt.InitWithValue(value) stmt_ := new(stmt.Stmt) stmt_.InitReturnStmt(return_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterExprStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == EXPR && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { expr_ := stack_items[0].Expr() expr_stmt := new(stmt.ExprStmt) expr_stmt.Init(expr_) stmt_ := new(stmt.Stmt) stmt_.InitExprStmt(expr_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterBlockStmt() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.LBRACE && stack_items[len(stack_items)-1].StackItemType() == TOKEN && stack_items[len(stack_items)-1].Token().TokenType() == lexer.RBRACE { for i := 1; i < len(stack_items)-1; i++ { if stack_items[i].StackItemType() != STMT { return false } } return true } else { return false } } reduce := func(stack_items []*StackItem) *StackItem { block_stmt := new(stmt.BlockStmt) block_stmt.Init() for i := 1; i < len(stack_items)-1; i++ { block_stmt.Append(stack_items[i].Stmt()) } stmt_ := new(stmt.Stmt) stmt_.InitBlockStmt(block_stmt) stack_item := new(StackItem) stack_item.InitStmt(stmt_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterStructDef() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TYPE_SPECIFIER && stack_items[0].TypeSpecifier().TypeSpecifierType() == type_specifier.STRUCT && stack_items[0].TypeSpecifier().NumStars() == 0 && stack_items[1].StackItemType() == STMT && stack_items[1].Stmt().StmtType() == stmt.BLOCK && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.SEMI { body := stack_items[1].Stmt().BlockStmt() for i := 0; i < body.Length(); i++ { stmt_ := body.Get(i) if stmt_.StmtType() != stmt.VAR_DECL { return false } } return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { type_specifier_ := stack_items[0].TypeSpecifier() body := stack_items[1].Stmt() identifier := type_specifier_.StructIdentifier() struct_def := new(decl.StructDef) struct_def.Init(identifier, body) decl_ := new(decl.Decl) decl_.InitStructDef(struct_def) stack_item := new(StackItem) stack_item.InitDecl(decl_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterFuncDeclEmpty() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.RPAREN && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() param_list_ := new(param_list.ParamList) param_list_.Init() func_decl := new(decl.FuncDecl) func_decl.Init(type_specifier_, identifier, param_list_) decl_ := new(decl.Decl) decl_.InitFuncDecl(func_decl) stack_item := new(StackItem) stack_item.InitDecl(decl_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterFuncDeclNonEmpty() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == PARAM_LIST && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.RPAREN && stack_items[4].StackItemType() == TOKEN && stack_items[4].Token().TokenType() == lexer.SEMI { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) param_list_ := stack_items[2].ParamList() type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() func_decl := new(decl.FuncDecl) func_decl.Init(type_specifier_, identifier, param_list_) decl_ := new(decl.Decl) decl_.InitFuncDecl(func_decl) stack_item := new(StackItem) stack_item.InitDecl(decl_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterFuncDefEmpty() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 4 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == TOKEN && stack_items[2].Token().TokenType() == lexer.RPAREN && stack_items[3].StackItemType() == STMT && stack_items[3].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) body := stack_items[3].Stmt() type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() param_list_ := new(param_list.ParamList) param_list_.Init() func_def := new(decl.FuncDef) func_def.Init(type_specifier_, identifier, param_list_, body) decl_ := new(decl.Decl) decl_.InitFuncDef(func_def) stack_item := new(StackItem) stack_item.InitDecl(decl_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterFuncDefNonEmpty() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 5 { return false } else { if stack_items[0].StackItemType() == PARAM_LIST && stack_items[0].ParamList().Length() == 1 && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.LPAREN && stack_items[2].StackItemType() == PARAM_LIST && stack_items[3].StackItemType() == TOKEN && stack_items[3].Token().TokenType() == lexer.RPAREN && stack_items[4].StackItemType() == STMT && stack_items[4].Stmt().StmtType() == stmt.BLOCK { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { param := stack_items[0].ParamList().Get(0) param_list_ := stack_items[2].ParamList() body := stack_items[4].Stmt() type_specifier_ := param.TypeSpecifier() identifier := param.Identifier() func_def := new(decl.FuncDef) func_def.Init(type_specifier_, identifier, param_list_, body) decl_ := new(decl.Decl) decl_.InitFuncDef(func_def) stack_item := new(StackItem) stack_item.InitDecl(decl_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterIncludeDirective() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 2 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.INCLUDE && stack_items[1].StackItemType() == TOKEN && stack_items[1].Token().TokenType() == lexer.HEADER { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { header := stack_items[1].Token() include_directive := new(directive.IncludeDirective) include_directive.Init(header) directive_ := new(directive.Directive) directive_.InitIncludeDirective(include_directive) stack_item := new(StackItem) stack_item.InitDirective(directive_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } func (this *Parser) RegisterDefineDirective() { precedence := map[lexer.TokenType]bool{} reducible := func(stack_items []*StackItem) bool { if len(stack_items) != 3 { return false } else { if stack_items[0].StackItemType() == TOKEN && stack_items[0].Token().TokenType() == lexer.DEFINE && stack_items[1].StackItemType() == EXPR && stack_items[1].Expr().ExprType() == expr.PRIMARY && stack_items[1].Expr().PrimaryExpr().PrimaryExprType() == expr.IDENTIFIER && stack_items[2].StackItemType() == EXPR { return true } else { return false } } } reduce := func(stack_items []*StackItem) *StackItem { lvalue := stack_items[1].Expr().PrimaryExpr().Token() rvalue := stack_items[2].Expr() define_directive := new(directive.DefineDirective) define_directive.Init(lvalue, rvalue) directive_ := new(directive.Directive) directive_.InitDefineDirective(define_directive) stack_item := new(StackItem) stack_item.InitDirective(directive_) return stack_item } rule := new(Rule) rule.Init(precedence, reducible, reduce) this.table.AddRule(rule) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/rule.go ================================================ package parser import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type Reducible func([]*StackItem) bool type Reduce func([]*StackItem) *StackItem type Rule struct { precedence map[lexer.TokenType]bool reducible Reducible reduce Reduce } func (this *Rule) Init(precedence map[lexer.TokenType]bool, reducible Reducible, reduce Reduce) { this.precedence = precedence this.reducible = reducible this.reduce = reduce } func (this *Rule) IsReducible(stack_items []*StackItem, token *lexer.Token) bool { if _, found := this.precedence[token.TokenType()]; found { return false } else { return this.reducible(stack_items) } } func (this *Rule) Reduce(stack_items []*StackItem, token *lexer.Token) *StackItem { if !this.IsReducible(stack_items, token) { err := errors.New("stack items are not reducible") panic(err) } return this.reduce(stack_items) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stack.go ================================================ package parser import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type Stack struct { stack_items []*StackItem } func (this *Stack) Init() { this.stack_items = make([]*StackItem, 0) } func (this *Stack) Length() int { return len(this.stack_items) } func (this *Stack) Push(stack_item *StackItem) { this.stack_items = append(this.stack_items, stack_item) } func (this *Stack) Pop(num int) { this.stack_items = this.stack_items[:len(this.stack_items)-num] } func (this *Stack) Front(num int) []*StackItem { stack_items := make([]*StackItem, 0) for i := 0; i < num; i++ { stack_item := this.stack_items[len(this.stack_items)-num+i] stack_items = append(stack_items, stack_item) } return stack_items } func (this *Stack) CanAccept() bool { for i, stack_item := range this.stack_items { if i < len(this.stack_items)-1 { if stack_item.StackItemType() != DIRECTIVE && stack_item.StackItemType() != DECL { return false } } else { if stack_item.StackItemType() != TOKEN || stack_item.Token().TokenType() != lexer.END_OF_FILE { return false } } } return true } func (this *Stack) Accept() *Ast { if !this.CanAccept() { err := errors.New("stack cannot be accepted") panic(err) } ast := new(Ast) ast.Init(this.stack_items[:len(this.stack_items)-1]) return ast } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stack_item.go ================================================ package parser import ( "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/decl" "uPIMulator/src/host/interpreter/parser/directive" "uPIMulator/src/host/interpreter/parser/expr" "uPIMulator/src/host/interpreter/parser/param_list" "uPIMulator/src/host/interpreter/parser/stmt" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type StackItemType int const ( TOKEN StackItemType = iota TYPE_SPECIFIER PARAM_LIST ARG_LIST EXPR STMT DECL DIRECTIVE ) type StackItem struct { stack_item_type StackItemType token *lexer.Token type_specifier *type_specifier.TypeSpecifier param_list *param_list.ParamList arg_list *expr.ArgList expr *expr.Expr stmt *stmt.Stmt decl *decl.Decl directive *directive.Directive } func (this *StackItem) InitToken(token *lexer.Token) { this.stack_item_type = TOKEN this.token = token } func (this *StackItem) InitTypeSpecifier(type_specifier *type_specifier.TypeSpecifier) { this.stack_item_type = TYPE_SPECIFIER this.type_specifier = type_specifier } func (this *StackItem) InitParamList(param_list *param_list.ParamList) { this.stack_item_type = PARAM_LIST this.param_list = param_list } func (this *StackItem) InitArgList(arg_list *expr.ArgList) { this.stack_item_type = ARG_LIST this.arg_list = arg_list } func (this *StackItem) InitExpr(expr *expr.Expr) { this.stack_item_type = EXPR this.expr = expr } func (this *StackItem) InitStmt(stmt *stmt.Stmt) { this.stack_item_type = STMT this.stmt = stmt } func (this *StackItem) InitDecl(decl *decl.Decl) { this.stack_item_type = DECL this.decl = decl } func (this *StackItem) InitDirective(directive *directive.Directive) { this.stack_item_type = DIRECTIVE this.directive = directive } func (this *StackItem) StackItemType() StackItemType { return this.stack_item_type } func (this *StackItem) Token() *lexer.Token { return this.token } func (this *StackItem) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *StackItem) ParamList() *param_list.ParamList { return this.param_list } func (this *StackItem) ArgList() *expr.ArgList { return this.arg_list } func (this *StackItem) Expr() *expr.Expr { return this.expr } func (this *StackItem) Stmt() *stmt.Stmt { return this.stmt } func (this *StackItem) Decl() *decl.Decl { return this.decl } func (this *StackItem) Directive() *directive.Directive { return this.directive } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/block_stmt.go ================================================ package stmt type BlockStmt struct { stmts []*Stmt } func (this *BlockStmt) Init() { this.stmts = make([]*Stmt, 0) } func (this *BlockStmt) Length() int { return len(this.stmts) } func (this *BlockStmt) Get(pos int) *Stmt { return this.stmts[pos] } func (this *BlockStmt) Append(stmt *Stmt) { this.stmts = append(this.stmts, stmt) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/break_stmt.go ================================================ package stmt type BreakStmt struct { } func (this *BreakStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/continue_stmt.go ================================================ package stmt type ContinueStmt struct { } func (this *ContinueStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/dpu_foreach_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/parser/expr" ) type DpuForeachStmt struct { foreach *expr.ArgList body *Stmt } func (this *DpuForeachStmt) Init(foreach *expr.ArgList, body *Stmt) { if foreach.Length() != 3 { err := errors.New("arg list's length != 3") panic(err) } else if body.StmtType() != BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.foreach = foreach this.body = body } func (this *DpuForeachStmt) Foreach() *expr.ArgList { return this.foreach } func (this *DpuForeachStmt) Body() *Stmt { return this.body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/empty_stmt.go ================================================ package stmt type EmptyStmt struct { } func (this *EmptyStmt) Init() { } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/expr_stmt.go ================================================ package stmt import ( "uPIMulator/src/host/interpreter/parser/expr" ) type ExprStmt struct { expr *expr.Expr } func (this *ExprStmt) Init(expr_ *expr.Expr) { this.expr = expr_ } func (this *ExprStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/for_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/parser/expr" ) type ForStmt struct { initialization *Stmt condition *expr.Expr update *Stmt body *Stmt } func (this *ForStmt) Init(initialization *Stmt, condition *expr.Expr, update *Stmt, body *Stmt) { if body.StmtType() != BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.initialization = initialization this.condition = condition this.update = update this.body = body } func (this *ForStmt) Initialization() *Stmt { return this.initialization } func (this *ForStmt) Condition() *expr.Expr { return this.condition } func (this *ForStmt) Update() *Stmt { return this.update } func (this *ForStmt) Body() *Stmt { return this.body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/if_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/parser/expr" ) type IfStmt struct { if_condition *expr.Expr if_body *Stmt else_if_conditions []*expr.Expr else_if_bodies []*Stmt else_body *Stmt } func (this *IfStmt) Init(if_condition *expr.Expr, if_body *Stmt) { if if_body.StmtType() != BLOCK { err := errors.New("if body's stmt type is not block") panic(err) } this.if_condition = if_condition this.if_body = if_body this.else_if_conditions = make([]*expr.Expr, 0) this.else_if_bodies = make([]*Stmt, 0) this.else_body = nil } func (this *IfStmt) IfCondition() *expr.Expr { return this.if_condition } func (this *IfStmt) IfBody() *Stmt { return this.if_body } func (this *IfStmt) NumElseIfs() int { if len(this.else_if_conditions) != len(this.else_if_bodies) { err := errors.New("lengths of else if conditions and bodies are different") panic(err) } return len(this.else_if_conditions) } func (this *IfStmt) ElseIfCondition(pos int) *expr.Expr { return this.else_if_conditions[pos] } func (this *IfStmt) ElseIfBody(pos int) *Stmt { return this.else_if_bodies[pos] } func (this *IfStmt) AppendElseIf(condition *expr.Expr, body *Stmt) { if body.StmtType() != BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.else_if_conditions = append(this.else_if_conditions, condition) this.else_if_bodies = append(this.else_if_bodies, body) } func (this *IfStmt) HasElseBody() bool { return this.else_body != nil } func (this *IfStmt) ElseBody() *Stmt { if !this.HasElseBody() { err := errors.New("else body does not exist") panic(err) } return this.else_body } func (this *IfStmt) SetElseBody(body *Stmt) { if this.HasElseBody() { err := errors.New("else body already exists") panic(err) } else if body.StmtType() != BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.else_body = body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/return_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/parser/expr" ) type ReturnStmt struct { value *expr.Expr } func (this *ReturnStmt) InitWithoutValue() { this.value = nil } func (this *ReturnStmt) InitWithValue(value *expr.Expr) { this.value = value } func (this *ReturnStmt) HasValue() bool { return this.value != nil } func (this *ReturnStmt) Value() *expr.Expr { if !this.HasValue() { err := errors.New("value does not exist") panic(err) } return this.value } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/stmt.go ================================================ package stmt type StmtType int const ( EMPTY StmtType = iota VAR_DECL VAR_DECL_INIT FOR DPU_FOREACH WHILE CONTINUE BREAK IF RETURN EXPR BLOCK ) type Stmt struct { stmt_type StmtType empty_stmt *EmptyStmt var_decl_stmt *VarDeclStmt var_decl_init_stmt *VarDeclInitStmt for_stmt *ForStmt dpu_foreach_stmt *DpuForeachStmt while_stmt *WhileStmt continue_stmt *ContinueStmt break_stmt *BreakStmt if_stmt *IfStmt return_stmt *ReturnStmt expr_stmt *ExprStmt block_stmt *BlockStmt } func (this *Stmt) InitEmptyStmt(empty_stmt *EmptyStmt) { this.stmt_type = EMPTY this.empty_stmt = empty_stmt } func (this *Stmt) InitVarDeclStmt(var_decl_stmt *VarDeclStmt) { this.stmt_type = VAR_DECL this.var_decl_stmt = var_decl_stmt } func (this *Stmt) InitVarDeclInitStmt(var_decl_init_stmt *VarDeclInitStmt) { this.stmt_type = VAR_DECL_INIT this.var_decl_init_stmt = var_decl_init_stmt } func (this *Stmt) InitForStmt(for_stmt *ForStmt) { this.stmt_type = FOR this.for_stmt = for_stmt } func (this *Stmt) InitDpuForeachStmt(dpu_foreach_stmt *DpuForeachStmt) { this.stmt_type = DPU_FOREACH this.dpu_foreach_stmt = dpu_foreach_stmt } func (this *Stmt) InitWhileStmt(while_stmt *WhileStmt) { this.stmt_type = WHILE this.while_stmt = while_stmt } func (this *Stmt) InitContinueStmt(continue_stmt *ContinueStmt) { this.stmt_type = CONTINUE this.continue_stmt = continue_stmt } func (this *Stmt) InitBreakStmt(break_stmt *BreakStmt) { this.stmt_type = BREAK this.break_stmt = break_stmt } func (this *Stmt) InitIfStmt(if_stmt *IfStmt) { this.stmt_type = IF this.if_stmt = if_stmt } func (this *Stmt) InitReturnStmt(return_stmt *ReturnStmt) { this.stmt_type = RETURN this.return_stmt = return_stmt } func (this *Stmt) InitExprStmt(expr_stmt *ExprStmt) { this.stmt_type = EXPR this.expr_stmt = expr_stmt } func (this *Stmt) InitBlockStmt(block_stmt *BlockStmt) { this.stmt_type = BLOCK this.block_stmt = block_stmt } func (this *Stmt) StmtType() StmtType { return this.stmt_type } func (this *Stmt) EmptyStmt() *EmptyStmt { return this.empty_stmt } func (this *Stmt) VarDeclStmt() *VarDeclStmt { return this.var_decl_stmt } func (this *Stmt) VarDeclInitStmt() *VarDeclInitStmt { return this.var_decl_init_stmt } func (this *Stmt) ForStmt() *ForStmt { return this.for_stmt } func (this *Stmt) DpuForeachStmt() *DpuForeachStmt { return this.dpu_foreach_stmt } func (this *Stmt) WhileStmt() *WhileStmt { return this.while_stmt } func (this *Stmt) ContinueStmt() *ContinueStmt { return this.continue_stmt } func (this *Stmt) BreakStmt() *BreakStmt { return this.break_stmt } func (this *Stmt) IfStmt() *IfStmt { return this.if_stmt } func (this *Stmt) ReturnStmt() *ReturnStmt { return this.return_stmt } func (this *Stmt) ExprStmt() *ExprStmt { return this.expr_stmt } func (this *Stmt) BlockStmt() *BlockStmt { return this.block_stmt } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/var_decl_init_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/expr" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type VarDeclInitStmt struct { type_specifier *type_specifier.TypeSpecifier identifier *lexer.Token expr *expr.Expr } func (this *VarDeclInitStmt) Init( type_specifier *type_specifier.TypeSpecifier, identifier *lexer.Token, expr_ *expr.Expr, ) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } this.type_specifier = type_specifier this.identifier = identifier this.expr = expr_ } func (this *VarDeclInitStmt) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *VarDeclInitStmt) Identifier() *lexer.Token { return this.identifier } func (this *VarDeclInitStmt) Expr() *expr.Expr { return this.expr } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/var_decl_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/lexer" "uPIMulator/src/host/interpreter/parser/type_specifier" ) type VarDeclStmt struct { type_specifier *type_specifier.TypeSpecifier identifier *lexer.Token } func (this *VarDeclStmt) Init( type_specifier *type_specifier.TypeSpecifier, identifier *lexer.Token, ) { if identifier.TokenType() != lexer.IDENTIFIER { err := errors.New("identifier's token type is not identifier") panic(err) } this.type_specifier = type_specifier this.identifier = identifier } func (this *VarDeclStmt) TypeSpecifier() *type_specifier.TypeSpecifier { return this.type_specifier } func (this *VarDeclStmt) Identifier() *lexer.Token { return this.identifier } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/stmt/while_stmt.go ================================================ package stmt import ( "errors" "uPIMulator/src/host/interpreter/parser/expr" ) type WhileStmt struct { condition *expr.Expr body *Stmt } func (this *WhileStmt) Init(condition *expr.Expr, body *Stmt) { if body.StmtType() != BLOCK { err := errors.New("body's stmt type is not block") panic(err) } this.condition = condition this.body = body } func (this *WhileStmt) Condition() *expr.Expr { return this.condition } func (this *WhileStmt) Body() *Stmt { return this.body } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/table.go ================================================ package parser import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type Table struct { rules []*Rule stack *Stack } func (this *Table) Init(stack *Stack) { this.rules = make([]*Rule, 0) this.stack = stack } func (this *Table) AddRule(rule *Rule) { this.rules = append(this.rules, rule) } func (this *Table) IsReducible(token *lexer.Token) bool { for i := 0; i < this.stack.Length(); i++ { stack_items := this.stack.Front(this.stack.Length() - i) for _, rule := range this.rules { if rule.IsReducible(stack_items, token) { return true } } } return false } func (this *Table) Reduce(token *lexer.Token) { for i := 0; i < this.stack.Length(); i++ { stack_items := this.stack.Front(this.stack.Length() - i) for _, rule := range this.rules { if rule.IsReducible(stack_items, token) { stack_item := rule.Reduce(stack_items, token) this.stack.Pop(len(stack_items)) this.stack.Push(stack_item) return } } } err := errors.New("stack is not reducible") panic(err) } ================================================ FILE: golang_vm/uPIMulator/src/host/interpreter/parser/type_specifier/type_specifier.go ================================================ package type_specifier import ( "errors" "uPIMulator/src/host/interpreter/lexer" ) type TypeSpecifierType int const ( VOID TypeSpecifierType = iota CHAR SHORT INT LONG STRUCT ) type TypeSpecifier struct { type_specifier_type TypeSpecifierType struct_identifier *lexer.Token num_stars int } func (this *TypeSpecifier) InitPrimitive(type_specifier_type TypeSpecifierType) { if type_specifier_type == STRUCT { err := errors.New("type specifier type is a struct") panic(err) } this.type_specifier_type = type_specifier_type this.struct_identifier = nil this.num_stars = 0 } func (this *TypeSpecifier) InitStruct( type_specifier_type TypeSpecifierType, struct_identifier *lexer.Token, ) { if type_specifier_type != STRUCT { err := errors.New("type specifier type is not a struct") panic(err) } this.type_specifier_type = type_specifier_type this.struct_identifier = struct_identifier this.num_stars = 0 } func (this *TypeSpecifier) TypeSpecifierType() TypeSpecifierType { return this.type_specifier_type } func (this *TypeSpecifier) StructIdentifier() *lexer.Token { if this.struct_identifier == nil { err := errors.New("struct identifier == nil") panic(err) } return this.struct_identifier } func (this *TypeSpecifier) NumStars() int { return this.num_stars } func (this *TypeSpecifier) AddStar() { this.num_stars++ } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/arena/arena.go ================================================ package arena import ( "uPIMulator/src/encoding" "uPIMulator/src/host/vm/base" "uPIMulator/src/host/vm/type_system" ) type Arena struct { pool *Pool } func (this *Arena) Init() { this.pool = new(Pool) this.pool.Init() } func (this *Arena) Pool() *Pool { return this.pool } func (this *Arena) NewChar(value int64) *base.Object { object := this.pool.Alloc(base.TEMPORARY, 1) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(value)) this.pool.Memory().Write(object.Address(), 1, byte_stream) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewShort(value int64) *base.Object { object := this.pool.Alloc(base.TEMPORARY, 2) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(value & 0xFF)) byte_stream.Append(uint8((value >> 8) & 0xFF)) this.pool.Memory().Write(object.Address(), 2, byte_stream) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewInt(value int64) *base.Object { object := this.pool.Alloc(base.TEMPORARY, 4) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(value & 0xFF)) byte_stream.Append(uint8((value >> 8) & 0xFF)) byte_stream.Append(uint8((value >> 16) & 0xFF)) byte_stream.Append(uint8((value >> 24) & 0xFF)) this.pool.Memory().Write(object.Address(), 4, byte_stream) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewLong(value int64) *base.Object { object := this.pool.Alloc(base.TEMPORARY, 8) byte_stream := new(encoding.ByteStream) byte_stream.Init() byte_stream.Append(uint8(value & 0xFF)) byte_stream.Append(uint8((value >> 8) & 0xFF)) byte_stream.Append(uint8((value >> 16) & 0xFF)) byte_stream.Append(uint8((value >> 24) & 0xFF)) byte_stream.Append(uint8((value >> 32) & 0xFF)) byte_stream.Append(uint8((value >> 40) & 0xFF)) byte_stream.Append(uint8((value >> 48) & 0xFF)) byte_stream.Append(uint8((value >> 56) & 0xFF)) this.pool.Memory().Write(object.Address(), 8, byte_stream) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewString(value string) *base.Object { object := this.pool.Alloc(base.TEMPORARY, int64(len(value))) ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() encoded_byte_stream := ascii_encoder.Encode(value) this.pool.Memory().Write(object.Address(), encoded_byte_stream.Size(), encoded_byte_stream) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.STRING, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewStruct(struct_name string, size int64) *base.Object { object := this.pool.Alloc(base.TEMPORARY, size) type_variable := new(type_system.TypeVariable) type_variable.InitStruct(type_system.STRUCT, struct_name, 0) object.SetTypeVariable(type_variable) return object } func (this *Arena) NewPointer(size int64) *base.Object { object := this.pool.Alloc(base.UNTEMPORARY, size) return object } func (this *Arena) Free(address int64) { this.pool.Free(address) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/arena/garbage_collector.go ================================================ package arena import ( "errors" "uPIMulator/src/host/vm/base" "uPIMulator/src/host/vm/frame" "uPIMulator/src/host/vm/symbol" "uPIMulator/src/host/vm/type_system" "uPIMulator/src/misc" ) type GarbageCollector struct { cycle int64 threshold int64 arena *Arena frame_chain *frame.FrameChain registry *type_system.TypeRegistry } func (this *GarbageCollector) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.cycle = 0 this.threshold = config_loader.GarbageCollectionThreshold() } func (this *GarbageCollector) ConnectArena(arena *Arena) { this.arena = arena } func (this *GarbageCollector) ConnectFrameChain(frame_chain *frame.FrameChain) { this.frame_chain = frame_chain } func (this *GarbageCollector) ConnectRegistry(registry *type_system.TypeRegistry) { this.registry = registry } func (this *GarbageCollector) MarkAndSweep() { if this.cycle > this.threshold { objects := this.Mark() this.Sweep(objects) this.cycle = 0 } this.cycle++ } func (this *GarbageCollector) Mark() []*base.Object { objects := make([]*base.Object, 0) for _, symbol_ := range this.frame_chain.Symbols() { objects = append(objects, this.ChaseSymbol(symbol_)...) } return objects } func (this *GarbageCollector) Sweep(objects []*base.Object) { for _, obj := range this.arena.Pool().Objects() { if obj.ObjectType() == base.TEMPORARY && !this.IsMarked(obj, objects) && !this.frame_chain.HasObject(obj.Address()) && this.arena.Pool().HasObject(obj.Address()) { this.arena.Free(obj.Address()) } } } func (this *GarbageCollector) ChaseSymbol(symbol_ *symbol.Symbol) []*base.Object { objects := make([]*base.Object, 0) type_variable := symbol_.TypeVariable() if type_variable.TypeVariableType() == type_system.VOID { if type_variable.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } objects = append(objects, this.ChaseObject(symbol_.Object())...) } else if type_variable.TypeVariableType() == type_system.CHAR { objects = append(objects, this.ChaseObject(symbol_.Object())...) } else if type_variable.TypeVariableType() == type_system.SHORT { objects = append(objects, this.ChaseObject(symbol_.Object())...) } else if type_variable.TypeVariableType() == type_system.INT { objects = append(objects, this.ChaseObject(symbol_.Object())...) } else if type_variable.TypeVariableType() == type_system.LONG { objects = append(objects, this.ChaseObject(symbol_.Object())...) } else if type_variable.TypeVariableType() == type_system.STRUCT { objects = append(objects, this.ChaseObject(symbol_.Object())...) } else { err := errors.New("type variable type is not valid") panic(err) } return objects } func (this *GarbageCollector) ChaseObject(object *base.Object) []*base.Object { objects := make([]*base.Object, 0) objects = append(objects, object) if !object.HasTypeVariable() { err := errors.New("object does not have a type variable") panic(err) } type_variable := object.TypeVariable() if type_variable.TypeVariableType() == type_system.VOID { if type_variable.NumStars() == 0 { err := errors.New("num stars == 0") panic(err) } if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } } else if type_variable.TypeVariableType() == type_system.CHAR { if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } } else if type_variable.TypeVariableType() == type_system.SHORT { if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } } else if type_variable.TypeVariableType() == type_system.INT { if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } } else if type_variable.TypeVariableType() == type_system.LONG { if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } } else if type_variable.TypeVariableType() == type_system.STRUCT { if type_variable.NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } else { struct_name := type_variable.StructName() skeleton := this.registry.Skeleton(struct_name) for i, field := range skeleton.Fields() { if i == 0 { if field.TypeVariable().NumStars() > 0 { value := this.arena.Pool().Memory().Read(object.Address(), 4).SignedValue() objects = append(objects, this.ChasePointer(value)...) } else { objects = append(objects, this.arena.Pool().Object(object.Address())) } } else { field_offset := this.registry.FieldOffset(skeleton.Name(), field.Name()) field_address := object.Address() + field_offset if this.arena.Pool().HasObject(field_address) { field_object := this.arena.Pool().Object(field_address) objects = append(objects, this.ChaseObject(field_object)...) } } } } } else { err := errors.New("type variable type is not valid") panic(err) } return objects } func (this *GarbageCollector) ChasePointer(address int64) []*base.Object { object := this.arena.Pool().Object(address) return this.ChaseObject(object) } func (this *GarbageCollector) IsMarked(object *base.Object, objects []*base.Object) bool { for _, obj := range objects { if obj == object { return true } } return false } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/arena/memory.go ================================================ package arena import ( "errors" "uPIMulator/src/encoding" ) type Memory struct { byte_stream *encoding.ByteStream } func (this *Memory) Init(size int64) { this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } } func (this *Memory) Size() int64 { return this.byte_stream.Size() } func (this *Memory) Resize(size int64) { if size < this.byte_stream.Size() { err := errors.New("size < byte stream's size") panic(err) } for i := int64(0); i < size-this.byte_stream.Size(); i++ { this.byte_stream.Append(0) } } func (this *Memory) Read(address int64, size int64) *encoding.ByteStream { for address+size >= this.byte_stream.Size() { this.Resize(2 * this.byte_stream.Size()) } byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { byte_stream.Append(this.byte_stream.Get(int(address + i))) } return byte_stream } func (this *Memory) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for address+size >= this.byte_stream.Size() { this.Resize(2 * this.byte_stream.Size()) } for i := int64(0); i < size; i++ { this.byte_stream.Set(int(address+i), byte_stream.Get(int(i))) } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/arena/pool.go ================================================ package arena import ( "errors" "fmt" "slices" "uPIMulator/src/encoding" "uPIMulator/src/host/vm/base" "uPIMulator/src/misc" ) type Pool struct { offset int64 objects []*base.Object memory *Memory } func (this *Pool) Init() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.offset = config_loader.VmBankOffset() this.objects = make([]*base.Object, 0) this.memory = new(Memory) this.memory.Init(config_loader.VmMemorySize()) } func (this *Pool) Memory() *Memory { return this.memory } func (this *Pool) Alloc(object_type base.ObjectType, size int64) *base.Object { cur_offset := this.offset if len(this.objects) == 0 { object := new(base.Object) object.Init(object_type, cur_offset, size) this.objects = append(this.objects, object) this.DoZeros(object) return object } else { for _, obj := range this.objects { if cur_offset+size <= obj.Address() { object := new(base.Object) object.Init(object_type, cur_offset, size) this.objects = append(this.objects, object) sort_fn := func(obj1 *base.Object, obj2 *base.Object) int { if obj1.Address() < obj2.Address() { return -1 } else if obj1.Address() == obj2.Address() { return 0 } else { return 1 } } slices.SortFunc(this.objects, sort_fn) this.DoZeros(object) return object } else { cur_offset = obj.Address() + obj.Size() } } object := new(base.Object) object.Init(object_type, cur_offset, size) this.objects = append(this.objects, object) this.DoZeros(object) return object } } func (this *Pool) Free(address int64) { if !this.HasObject(address) { err_msg := fmt.Sprintf("object with address (%d) is not found", address) err := errors.New(err_msg) panic(err) } for i, object := range this.objects { if object.Address() == address { this.objects = append(this.objects[:i], this.objects[i+1:]...) break } } } func (this *Pool) HasObject(address int64) bool { for _, object := range this.objects { if object.Address() == address { return true } } return false } func (this *Pool) Object(address int64) *base.Object { if !this.HasObject(address) { err_msg := fmt.Sprintf("object with address (%d) is not found", address) err := errors.New(err_msg) panic(err) } for _, object := range this.objects { if object.Address() == address { return object } } return nil } func (this *Pool) HasLastObject(address int64) bool { for i := len(this.objects) - 1; i >= 0; i-- { object := this.objects[i] if object.Address() == address { return true } } return false } func (this *Pool) LastObject(address int64) *base.Object { if !this.HasLastObject(address) { err_msg := fmt.Sprintf("object with address (%d) is not found", address) err := errors.New(err_msg) panic(err) } for i := len(this.objects) - 1; i >= 0; i-- { object := this.objects[i] if object.Address() == address { return object } } return nil } func (this *Pool) Objects() []*base.Object { return this.objects } func (this *Pool) DoZeros(object *base.Object) { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < object.Size(); i++ { byte_stream.Append(0) } this.memory.Write(object.Address(), object.Size(), byte_stream) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/bank_cycle_job.go ================================================ package vm import ( "uPIMulator/src/host/vm/dram/bank" ) type BankCycleJob struct { bank *bank.Bank } func (this *BankCycleJob) Init(bank_ *bank.Bank) { this.bank = bank_ } func (this *BankCycleJob) Execute() { this.bank.Cycle() } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/base/object.go ================================================ package base import ( "errors" "uPIMulator/src/host/vm/type_system" ) type ObjectType int const ( TEMPORARY ObjectType = iota UNTEMPORARY ) type Object struct { object_type ObjectType type_variable *type_system.TypeVariable address int64 size int64 } func (this *Object) Init(object_type ObjectType, address int64, size int64) { if address <= 0 { err := errors.New("address <= 0") panic(err) } else if size <= 0 { err := errors.New("size <= 0") panic(err) } this.object_type = object_type this.address = address this.size = size } func (this *Object) ObjectType() ObjectType { return this.object_type } func (this *Object) HasTypeVariable() bool { return this.type_variable != nil } func (this *Object) TypeVariable() *type_system.TypeVariable { return this.type_variable } func (this *Object) SetTypeVariable(type_variable *type_system.TypeVariable) { if this.type_variable != nil { err := errors.New("type variable != nil") panic(err) } this.type_variable = type_variable } func (this *Object) Address() int64 { return this.address } func (this *Object) Size() int64 { return this.size } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dpu_compute_cycle_job.go ================================================ package vm import ( "uPIMulator/src/device/simulator/dpu" "uPIMulator/src/device/simulator/dpu/logic" ) type DpuComputeCycleJob struct { sys_end int64 dpu *dpu.Dpu } func (this *DpuComputeCycleJob) Init(sys_end int64, dpu_ *dpu.Dpu) { this.sys_end = sys_end this.dpu = dpu_ } func (this *DpuComputeCycleJob) Execute() { for !this.dpu.IsZombie() { for _, thread := range this.dpu.Threads() { if thread.RegFile().ReadPcReg() == this.sys_end && thread.ThreadState() == logic.SLEEP { this.dpu.ThreadScheduler().Shutdown(thread.ThreadId()) } } this.dpu.Cycle() } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dpu_cycle_job.go ================================================ package vm import ( "uPIMulator/src/device/simulator/dpu" ) type DpuCycleJob struct { dpu *dpu.Dpu } func (this *DpuCycleJob) Init(dpu_ *dpu.Dpu) { this.dpu = dpu_ } func (this *DpuCycleJob) Execute() { this.dpu.Cycle() } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dpu_load_job.go ================================================ package vm import ( "uPIMulator/src/device/simulator/dpu" "uPIMulator/src/misc" "uPIMulator/src/program" ) type DpuLoadJob struct { task *program.Task dpu *dpu.Dpu } func (this *DpuLoadJob) Init(task *program.Task, dpu_ *dpu.Dpu) { this.task = task this.dpu = dpu_ } func (this *DpuLoadJob) Execute() { config_loader := new(misc.ConfigLoader) config_loader.Init() this.dpu.Dma(). TransferToAtomic(config_loader.AtomicOffset(), this.task.Atomic().Size(), this.task.Atomic()) this.dpu.Dma(). TransferToIram(config_loader.IramOffset(), this.task.Iram().Size(), this.task.Iram()) this.dpu.Dma(). TransferToWram(config_loader.WramOffset(), this.task.Wram().Size(), this.task.Wram()) this.dpu.Dma(). TransferToMram(config_loader.MramOffset(), this.task.Mram().Size(), this.task.Mram()) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/array.go ================================================ package bank import ( "errors" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Array struct { channel_id int rank_id int bank_id int address int64 size int64 wordline_size int64 wordlines []*Wordline } func (this *Array) Init(command_line_parser *misc.CommandLineParser) { config_loader := new(misc.ConfigLoader) config_loader.Init() this.address = 0 this.size = config_loader.VmBankSize() this.wordline_size = command_line_parser.IntParameter("wordline_size") if this.wordline_size <= 0 { err := errors.New("wordline size <= 0") panic(err) } else if this.address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if this.size%this.wordline_size != 0 { err := errors.New("size is not aligned with wordline size") panic(err) } this.wordlines = make([]*Wordline, 0) num_wordlines := int(this.size / this.wordline_size) for i := 0; i < num_wordlines; i++ { wordline := new(Wordline) wordline.Init(this.address+int64(i)*this.wordline_size, this.wordline_size) this.wordlines = append(this.wordlines, wordline) } } func (this *Array) Fini() { for _, wordline := range this.wordlines { wordline.Fini() } } func (this *Array) Address() int64 { return this.address } func (this *Array) Size() int64 { return this.size } func (this *Array) Read(address int64) *encoding.ByteStream { return this.wordlines[this.Index(address)].Read() } func (this *Array) Write(address int64, byte_stream *encoding.ByteStream) { this.wordlines[this.Index(address)].Write(byte_stream) } func (this *Array) Index(address int64) int { if address < this.address { err := errors.New("address < MRAM offset") panic(err) } else if address+this.wordline_size > this.address+this.size { err := errors.New("address + wordline size > MRAM offset + MRAM size") panic(err) } else if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } return int((address - this.address) / this.wordline_size) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/bank.go ================================================ package bank import ( "errors" "fmt" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Bank struct { channel_id int rank_id int bank_id int wordline_size int64 array *Array row_buffer *RowBuffer input_q *MemoryCommandQ ready_q *MemoryCommandQ stat_factory *misc.StatFactory } func (this *Bank) Init( channel_id int, rank_id int, bank_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if bank_id < 0 { err := errors.New("bank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.bank_id = bank_id this.wordline_size = command_line_parser.IntParameter("wordline_size") this.array = new(Array) this.array.Init(command_line_parser) this.row_buffer = new(RowBuffer) this.row_buffer.Init(channel_id, rank_id, bank_id, command_line_parser) this.row_buffer.ConnectArray(this.array) this.input_q = new(MemoryCommandQ) this.input_q.Init(-1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) name := fmt.Sprintf("VmBank[%d_%d_%d]", channel_id, rank_id, bank_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *Bank) Fini() { this.array.Fini() this.row_buffer.Fini() this.input_q.Fini() this.ready_q.Fini() } func (this *Bank) ChannelId() int { return this.channel_id } func (this *Bank) RankId() int { return this.rank_id } func (this *Bank) DpuId() int { return this.bank_id } func (this *Bank) RowBuffer() *RowBuffer { return this.row_buffer } func (this *Bank) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *Bank) IsEmpty() bool { return this.row_buffer.IsEmpty() && this.input_q.IsEmpty() && this.ready_q.IsEmpty() } func (this *Bank) CanPush() bool { return this.input_q.CanPush(1) } func (this *Bank) Push(memory_command *MemoryCommand) { if !this.CanPush() { err := errors.New("bank cannot be pushed") panic(err) } this.input_q.Push(memory_command) } func (this *Bank) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Bank) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("bank cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Bank) Read(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.array.Read(cur_wordline_address) for i := cur_offset; i < cur_offset+cur_size; i++ { byte_stream.Append(mram_byte_stream.Get(int(i))) } cur_address += cur_size } return byte_stream } func (this *Bank) Write(address int64, size int64, byte_stream *encoding.ByteStream) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } cur_byte_stream_offset := int64(0) for cur_address := address; cur_address < address+size; { cur_wordline_address := this.WordlineAddress(cur_address) cur_size := this.Min(cur_wordline_address+this.wordline_size, address+size) - cur_address cur_offset := cur_address % this.wordline_size mram_byte_stream := this.array.Read(cur_wordline_address) for i := int64(0); i < cur_size; i++ { mram_byte_stream.Set(int(i+cur_offset), byte_stream.Get(int(i+cur_byte_stream_offset))) } this.array.Write(cur_wordline_address, mram_byte_stream) cur_address += cur_size cur_byte_stream_offset += cur_size } } func (this *Bank) Flush() { this.row_buffer.Flush() } func (this *Bank) Cycle() { this.ServiceInputQ() this.ServiceRowBuffer() this.row_buffer.Cycle() this.input_q.Cycle() this.ready_q.Cycle() this.stat_factory.Increment("vm_memory_cycle", 1) } func (this *Bank) ServiceInputQ() { if this.input_q.CanPop(1) && this.row_buffer.CanPush() { memory_command := this.input_q.Pop() this.row_buffer.Push(memory_command) } } func (this *Bank) ServiceRowBuffer() { if this.row_buffer.CanPop() && this.ready_q.CanPush(1) { memory_command := this.row_buffer.Pop() memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { return } else if memory_operation == PRECHARGE { return } else if memory_operation == READ { address := memory_command.BankAddress() size := memory_command.Size() byte_stream := memory_command.ByteStream() dma_command := memory_command.DmaCommand() dma_command.SetByteStream(address, size, byte_stream) dma_command.SetAck(address, size) } else if memory_operation == WRITE { address := memory_command.BankAddress() size := memory_command.Size() dma_command := memory_command.DmaCommand() dma_command.SetAck(address, size) } else { err := errors.New("memory operation is not valid") panic(err) } this.ready_q.Push(memory_command) } } func (this *Bank) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *Bank) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/dma_command.go ================================================ package bank import ( "errors" "uPIMulator/src/encoding" ) type DmaCommand struct { memory_operation MemoryOperation segment *Segment byte_stream *encoding.ByteStream acks []bool transfer_command *TransferCommand } func (this *DmaCommand) InitRead(segment *Segment, transfer_command *TransferCommand) { this.memory_operation = READ this.segment = segment this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() this.acks = make([]bool, 0) for i := int64(0); i < segment.Size(); i++ { this.byte_stream.Append(0) this.acks = append(this.acks, false) } this.transfer_command = transfer_command } func (this *DmaCommand) InitWrite(segment *Segment, transfer_command *TransferCommand) { this.memory_operation = WRITE this.segment = segment this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() this.acks = make([]bool, 0) for i := int64(0); i < segment.Size(); i++ { this.byte_stream.Append(0) this.acks = append(this.acks, false) } this.transfer_command = transfer_command } func (this *DmaCommand) Fini() { if !this.IsReady() { err := errors.New("DMA command is not ready") panic(err) } } func (this *DmaCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *DmaCommand) Segment() *Segment { return this.segment } func (this *DmaCommand) ByteStream(bank_address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(bank_address) + int(i) byte_stream.Append(this.byte_stream.Get(index)) } return byte_stream } func (this *DmaCommand) SetByteStream( bank_address int64, size int64, byte_stream *encoding.ByteStream, ) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(bank_address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *DmaCommand) SetAck(bank_address int64, size int64) { for i := int64(0); i < size; i++ { index := this.Index(bank_address) + int(i) if this.acks[index] { err := errors.New("ACK is already set") panic(err) } this.acks[index] = true } } func (this *DmaCommand) IsReady() bool { for _, ack := range this.acks { if !ack { return false } } return true } func (this *DmaCommand) TransferCommand() *TransferCommand { return this.transfer_command } func (this *DmaCommand) Index(bank_address int64) int { if bank_address < this.segment.BankAddress() { err := errors.New("bank address < DMA command's segment's bank address") panic(err) } else if bank_address >= this.segment.BankAddress()+this.segment.Size() { err := errors.New("bank address >= DMA command's segment's bank address + DMA command's size") panic(err) } return int(bank_address - this.segment.BankAddress()) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/dma_command_q.go ================================================ package bank import ( "errors" ) type DmaCommandQ struct { size int timer int64 dma_commands []*DmaCommand cycles []int64 } func (this *DmaCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.dma_commands = make([]*DmaCommand, 0) this.cycles = make([]int64, 0) } func (this *DmaCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("DMA command queue is not empty") panic(err) } } func (this *DmaCommandQ) Size() int { return this.size } func (this *DmaCommandQ) Length() int { return len(this.dma_commands) } func (this *DmaCommandQ) Timer() int64 { return this.timer } func (this *DmaCommandQ) IsEmpty() bool { return len(this.dma_commands) == 0 } func (this *DmaCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.dma_commands) >= num_items } else { return true } } func (this *DmaCommandQ) Push(dma_command *DmaCommand) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, this.timer) } func (this *DmaCommandQ) PushWithTimer(dma_command *DmaCommand, timer int64) { if !this.CanPush(1) { err := errors.New("DMA command queue cannot be pushed") panic(err) } this.dma_commands = append(this.dma_commands, dma_command) this.cycles = append(this.cycles, timer) } func (this *DmaCommandQ) CanPop(num_items int) bool { if len(this.dma_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *DmaCommandQ) Pop() *DmaCommand { if !this.CanPop(1) { err := errors.New("DMA command queue cannot be popped") panic(err) } dma_command := this.dma_commands[0] this.dma_commands = this.dma_commands[1:] this.cycles = this.cycles[1:] return dma_command } func (this *DmaCommandQ) Front(pos int) (*DmaCommand, int64) { return this.dma_commands[pos], this.cycles[pos] } func (this *DmaCommandQ) Remove(pos int) { this.dma_commands = append(this.dma_commands[:pos], this.dma_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *DmaCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/memory_command.go ================================================ package bank import ( "errors" "uPIMulator/src/encoding" ) type MemoryOperation int const ( ACTIVATION MemoryOperation = iota READ WRITE PRECHARGE ) type MemoryCommand struct { memory_operation MemoryOperation bank_address int64 size int64 byte_stream *encoding.ByteStream dma_command *DmaCommand } func (this *MemoryCommand) InitActivation(memory_operation MemoryOperation, bank_address int64) { this.memory_operation = memory_operation this.bank_address = bank_address this.size = 0 this.byte_stream = nil this.dma_command = nil } func (this *MemoryCommand) InitRead( memory_operation MemoryOperation, bank_address int64, size int64, dma_command *DmaCommand, ) { if memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } else if dma_command.MemoryOperation() != READ { err := errors.New("DMA operation != READ") panic(err) } this.memory_operation = memory_operation this.bank_address = bank_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.dma_command = dma_command } func (this *MemoryCommand) InitWrite( memory_operation MemoryOperation, bank_address int64, size int64, byte_stream *encoding.ByteStream, dma_command *DmaCommand, ) { if memory_operation != WRITE { err := errors.New("memory operation != WRITE") panic(err) } else if dma_command.MemoryOperation() != WRITE { err := errors.New("DMA operation != WRITE") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } this.memory_operation = memory_operation this.bank_address = bank_address this.size = size this.byte_stream = byte_stream this.dma_command = dma_command } func (this *MemoryCommand) MemoryOperation() MemoryOperation { return this.memory_operation } func (this *MemoryCommand) BankAddress() int64 { return this.bank_address } func (this *MemoryCommand) Size() int64 { return this.size } func (this *MemoryCommand) ByteStream() *encoding.ByteStream { if this.byte_stream == nil { err := errors.New("byte stream == nil") panic(err) } return this.byte_stream } func (this *MemoryCommand) SetByteStream(byte_stream *encoding.ByteStream) { if this.memory_operation != READ { err := errors.New("memory operation != READ") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } func (this *MemoryCommand) DmaCommand() *DmaCommand { if this.dma_command == nil { err := errors.New("DMA command == nil") panic(err) } return this.dma_command } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/memory_command_q.go ================================================ package bank import ( "errors" ) type MemoryCommandQ struct { size int timer int64 memory_commands []*MemoryCommand cycles []int64 } func (this *MemoryCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.memory_commands = make([]*MemoryCommand, 0) this.cycles = make([]int64, 0) } func (this *MemoryCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("memory command queue is not empty") panic(err) } } func (this *MemoryCommandQ) Size() int { return this.size } func (this *MemoryCommandQ) Length() int { return len(this.memory_commands) } func (this *MemoryCommandQ) Timer() int64 { return this.timer } func (this *MemoryCommandQ) IsEmpty() bool { return len(this.memory_commands) == 0 } func (this *MemoryCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.memory_commands) >= num_items } else { return true } } func (this *MemoryCommandQ) Push(memory_command *MemoryCommand) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, this.timer) } func (this *MemoryCommandQ) PushWithTimer(memory_command *MemoryCommand, timer int64) { if !this.CanPush(1) { err := errors.New("memory command queue cannot be pushed") panic(err) } this.memory_commands = append(this.memory_commands, memory_command) this.cycles = append(this.cycles, timer) } func (this *MemoryCommandQ) CanPop(num_items int) bool { if len(this.memory_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *MemoryCommandQ) Pop() *MemoryCommand { if !this.CanPop(1) { err := errors.New("memory command queue cannot be popped") panic(err) } memory_command := this.memory_commands[0] this.memory_commands = this.memory_commands[1:] this.cycles = this.cycles[1:] return memory_command } func (this *MemoryCommandQ) Front(pos int) (*MemoryCommand, int64) { return this.memory_commands[pos], this.cycles[pos] } func (this *MemoryCommandQ) Remove(pos int) { this.memory_commands = append(this.memory_commands[:pos], this.memory_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *MemoryCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/row_buffer.go ================================================ package bank import ( "errors" "fmt" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type RowBuffer struct { channel_id int rank_id int bank_id int t_ras int64 t_rcd int64 t_cl int64 t_bl int64 t_rp int64 wordline_size int64 array *Array row_address *int64 row_buffer *encoding.ByteStream input_q *MemoryCommandQ ready_q *MemoryCommandQ activation_q *MemoryCommandQ io_q *MemoryCommandQ bus_q *MemoryCommandQ precharge_q *MemoryCommandQ stat_factory *misc.StatFactory } func (this *RowBuffer) Init( channel_id int, rank_id int, bank_id int, command_line_parser *misc.CommandLineParser, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if bank_id < 0 { err := errors.New("bank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.bank_id = bank_id this.t_ras = command_line_parser.IntParameter("t_ras") this.t_rcd = command_line_parser.IntParameter("t_rcd") this.t_cl = command_line_parser.IntParameter("t_cl") this.t_bl = command_line_parser.IntParameter("t_bl") this.t_rp = command_line_parser.IntParameter("t_rp") this.wordline_size = command_line_parser.IntParameter("wordline_size") this.array = nil this.row_address = nil this.row_buffer = nil this.input_q = new(MemoryCommandQ) this.input_q.Init(1, 0) this.ready_q = new(MemoryCommandQ) this.ready_q.Init(-1, 0) this.activation_q = new(MemoryCommandQ) this.activation_q.Init(1, this.t_ras) this.io_q = new(MemoryCommandQ) this.io_q.Init(1, this.t_cl) this.bus_q = new(MemoryCommandQ) this.bus_q.Init(1, this.t_bl) this.precharge_q = new(MemoryCommandQ) this.precharge_q.Init(1, this.t_rp) name := fmt.Sprintf("VmRowBuffer[%d_%d_%d]", channel_id, rank_id, bank_id) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init(name) } func (this *RowBuffer) Fini() { this.input_q.Fini() this.ready_q.Fini() this.activation_q.Fini() this.io_q.Fini() this.bus_q.Fini() this.precharge_q.Fini() } func (this *RowBuffer) ConnectArray(array *Array) { if this.array != nil { err := errors.New("array is already connected") panic(err) } this.array = array } func (this *RowBuffer) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *RowBuffer) IsEmpty() bool { return this.input_q.IsEmpty() && this.ready_q.IsEmpty() && this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() } func (this *RowBuffer) CanPush() bool { return this.input_q.CanPush(1) } func (this *RowBuffer) Push(memory_command *MemoryCommand) { if !this.CanPush() { err := errors.New("row buffer cannot be pushed") panic(err) } this.input_q.Push(memory_command) } func (this *RowBuffer) CanPop() bool { return this.ready_q.CanPop(1) } func (this *RowBuffer) Pop() *MemoryCommand { if !this.CanPop() { err := errors.New("row buffer cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *RowBuffer) Flush() { if this.row_address != nil { this.WriteToBank() this.row_address = nil this.row_buffer = nil } } func (this *RowBuffer) Cycle() { this.ServiceInputQ() this.ServiceActivationQ() this.ServiceIoQ() this.ServiceBusQ() this.ServicePrechargeQ() this.input_q.Cycle() this.ready_q.Cycle() this.activation_q.Cycle() this.io_q.Cycle() this.bus_q.Cycle() this.precharge_q.Cycle() } func (this *RowBuffer) ServiceInputQ() { if this.input_q.CanPop(1) { memory_command, _ := this.input_q.Front(0) memory_operation := memory_command.MemoryOperation() if memory_operation == ACTIVATION { if this.activation_q.IsEmpty() && this.row_address == nil { this.activation_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == READ { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == WRITE { if this.io_q.CanPush(1) && this.row_address != nil { this.io_q.Push(memory_command) this.input_q.Pop() } } else if memory_operation == PRECHARGE { if this.activation_q.IsEmpty() && this.io_q.IsEmpty() && this.bus_q.IsEmpty() && this.precharge_q.IsEmpty() { this.precharge_q.Push(memory_command) this.input_q.Pop() } } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServiceActivationQ() { if !this.activation_q.IsEmpty() { memory_command, cycle := this.activation_q.Front(0) if cycle == this.t_ras-this.t_rcd { if this.row_address != nil { err := errors.New("row buffer is not precharged") panic(err) } else if memory_command.BankAddress()%this.wordline_size != 0 { err := errors.New("memory command is not aligned with wordline size") panic(err) } this.row_address = new(int64) *this.row_address = memory_command.BankAddress() this.row_buffer = this.ReadFromBank() } } if this.activation_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.activation_q.Pop() this.ready_q.Push(memory_command) this.stat_factory.Increment("num_activations", 1) } } func (this *RowBuffer) ServiceIoQ() { if this.io_q.CanPop(1) && this.bus_q.CanPush(1) { memory_command := this.io_q.Pop() this.bus_q.Push(memory_command) } } func (this *RowBuffer) ServiceBusQ() { if this.bus_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.bus_q.Pop() this.ready_q.Push(memory_command) memory_operation := memory_command.MemoryOperation() if memory_operation == READ { byte_stream := this.ReadFromRowBuffer( memory_command.BankAddress(), memory_command.Size(), ) memory_command.SetByteStream(byte_stream) this.stat_factory.Increment("num_reads", 1) this.stat_factory.Increment("read_bytes", memory_command.Size()) } else if memory_operation == WRITE { this.WriteToRowBuffer(memory_command.BankAddress(), memory_command.Size(), memory_command.ByteStream()) this.stat_factory.Increment("num_writes", 1) this.stat_factory.Increment("write_bytes", memory_command.Size()) } else { err := errors.New("memory operation is not valid") panic(err) } } } func (this *RowBuffer) ServicePrechargeQ() { if this.precharge_q.CanPop(1) && this.ready_q.CanPush(1) { memory_command := this.precharge_q.Pop() address := memory_command.BankAddress() if address%this.wordline_size != 0 { err := errors.New("address is not aligned with wordline size") panic(err) } else if address != *this.row_address { err := errors.New("address != row address") panic(err) } this.WriteToBank() this.row_address = nil this.ready_q.Push(memory_command) this.stat_factory.Increment("num_precharges", 1) } } func (this *RowBuffer) ReadFromBank() *encoding.ByteStream { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } return this.array.Read(*this.row_address) } func (this *RowBuffer) ReadFromRowBuffer(address int64, size int64) *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { index := this.Index(address) + int(i) byte_stream.Append(this.row_buffer.Get(index)) } return byte_stream } func (this *RowBuffer) WriteToBank() { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } this.array.Write(*this.row_address, this.row_buffer) } func (this *RowBuffer) WriteToRowBuffer( address int64, size int64, byte_stream *encoding.ByteStream, ) { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(address) + int(i) this.row_buffer.Set(index, byte_stream.Get(int(i))) } } func (this *RowBuffer) Index(address int64) int { if this.row_address == nil { err := errors.New("row address is not set") panic(err) } else if address < *this.row_address { err := errors.New("address < row address") panic(err) } else if address >= *this.row_address+this.wordline_size { err := errors.New("address >= row address + wordline size") panic(err) } return int(address - *this.row_address) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/segment.go ================================================ package bank import ( "errors" ) type Segment struct { vm_address int64 channel_id int rank_id int bank_id int bank_address int64 size int64 } func (this *Segment) Init( vm_address int64, channel_id int, rank_id int, bank_id int, bank_address int64, size int64, ) { if vm_address < 0 { err := errors.New("VM segment < 0") panic(err) } else if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if bank_id < 0 { err := errors.New("DPU ID < 0") panic(err) } else if bank_address < 0 { err := errors.New("bank segment < 0") panic(err) } else if size < 0 { err := errors.New("size < 0") panic(err) } this.vm_address = vm_address this.channel_id = channel_id this.rank_id = rank_id this.bank_id = bank_id this.bank_address = bank_address this.size = size } func (this *Segment) VmAddress() int64 { return this.vm_address } func (this *Segment) ChannelID() int { return this.channel_id } func (this *Segment) RankID() int { return this.rank_id } func (this *Segment) BankID() int { return this.bank_id } func (this *Segment) BankAddress() int64 { return this.bank_address } func (this *Segment) Size() int64 { return this.size } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/transfer_command.go ================================================ package bank import ( "errors" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/encoding" ) type TransferCommandType int const ( HOST_TO_DEVICE TransferCommandType = iota DEVICE_TO_HOST ) type TransferCommandState int const ( BEGIN TransferCommandState = iota MIDDLE END ) type TransferCommand struct { transfer_command_type TransferCommandType transfer_command_state TransferCommandState vm_address int64 channel_id int rank_id int dpu_id int mram_address int64 size int64 byte_stream *encoding.ByteStream vm_dma_commands map[*DmaCommand]bool dma_commands map[*dram.DmaCommand]bool } func (this *TransferCommand) Init( transfer_command_type TransferCommandType, vm_address int64, channel_id int, rank_id int, dpu_id int, mram_address int64, size int64, ) { this.transfer_command_type = transfer_command_type this.transfer_command_state = BEGIN this.vm_address = vm_address this.channel_id = channel_id this.rank_id = rank_id this.dpu_id = dpu_id this.mram_address = mram_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } this.vm_dma_commands = make(map[*DmaCommand]bool) this.dma_commands = make(map[*dram.DmaCommand]bool) } func (this *TransferCommand) InitFast(vm_address int64, size int64) { this.vm_address = vm_address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } } func (this *TransferCommand) TransferCommandType() TransferCommandType { return this.transfer_command_type } func (this *TransferCommand) VmAddress() int64 { return this.vm_address } func (this *TransferCommand) ChannelId() int { return this.channel_id } func (this *TransferCommand) RankId() int { return this.rank_id } func (this *TransferCommand) DpuId() int { return this.dpu_id } func (this *TransferCommand) MramAddress() int64 { return this.mram_address } func (this *TransferCommand) Size() int64 { return this.size } func (this *TransferCommand) ByteStream() *encoding.ByteStream { return this.byte_stream } func (this *TransferCommand) SetByteStream( vm_address int64, size int64, byte_stream *encoding.ByteStream, ) { if size != byte_stream.Size() { err := errors.New("size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { index := this.Index(vm_address) + int(i) this.byte_stream.Set(index, byte_stream.Get(int(i))) } } func (this *TransferCommand) AppendVmDmaCommand(vm_dma_command *DmaCommand) { this.vm_dma_commands[vm_dma_command] = true } func (this *TransferCommand) AppendDmaCommand(dma_command *dram.DmaCommand) { this.dma_commands[dma_command] = true } func (this *TransferCommand) AckVmDmaCommand(vm_dma_command *DmaCommand) { if !vm_dma_command.IsReady() { err := errors.New("VM DMA command is not ready") panic(err) } if _, found := this.vm_dma_commands[vm_dma_command]; found { delete(this.vm_dma_commands, vm_dma_command) } else { err := errors.New("VM DMA command is not found") panic(err) } } func (this *TransferCommand) AckDmaCommand(dma_command *dram.DmaCommand) { if !dma_command.IsReady() { err := errors.New("DMA command is not ready") panic(err) } if _, found := this.dma_commands[dma_command]; found { delete(this.dma_commands, dma_command) } else { err := errors.New("DMA command is not found") panic(err) } } func (this *TransferCommand) IsVmReady() bool { return len(this.vm_dma_commands) == 0 } func (this *TransferCommand) IsReady() bool { return len(this.dma_commands) == 0 } func (this *TransferCommand) TransferCommandState() TransferCommandState { return this.transfer_command_state } func (this *TransferCommand) SetTransferCommandState(transfer_command_state TransferCommandState) { if transfer_command_state == BEGIN { err := errors.New("transfer command state is begin") panic(err) } else if transfer_command_state == MIDDLE { if this.transfer_command_state != BEGIN { err := errors.New("transfer command state is middle, but current transfer command state is not begin") panic(err) } this.transfer_command_state = transfer_command_state } else if transfer_command_state == END { if this.transfer_command_state != MIDDLE { err := errors.New("transfer command state is end, but current transfer command state is not middle") panic(err) } this.transfer_command_state = transfer_command_state } else { err := errors.New("transfer command state is not valid") panic(err) } } func (this *TransferCommand) Index(vm_address int64) int { if vm_address < this.vm_address { err := errors.New("VM address < transfer command's VM address") panic(err) } else if vm_address >= this.vm_address+this.size { err := errors.New("VM address >= transfer command's VM address + transfer command's size") panic(err) } return int(vm_address - this.vm_address) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/transfer_command_q.go ================================================ package bank import ( "errors" ) type TransferCommandQ struct { size int timer int64 transfer_commands []*TransferCommand cycles []int64 } func (this *TransferCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.transfer_commands = make([]*TransferCommand, 0) this.cycles = make([]int64, 0) } func (this *TransferCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("transfer command queue is not empty") panic(err) } } func (this *TransferCommandQ) Size() int { return this.size } func (this *TransferCommandQ) Length() int { return len(this.transfer_commands) } func (this *TransferCommandQ) Timer() int64 { return this.timer } func (this *TransferCommandQ) IsEmpty() bool { return len(this.transfer_commands) == 0 } func (this *TransferCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.transfer_commands) >= num_items } else { return true } } func (this *TransferCommandQ) Push(transfer_command *TransferCommand) { if !this.CanPush(1) { err := errors.New("transfer command queue cannot be pushed") panic(err) } this.transfer_commands = append(this.transfer_commands, transfer_command) this.cycles = append(this.cycles, this.timer) } func (this *TransferCommandQ) PushWithTimer(transfer_command *TransferCommand, timer int64) { if !this.CanPush(1) { err := errors.New("transfer command queue cannot be pushed") panic(err) } this.transfer_commands = append(this.transfer_commands, transfer_command) this.cycles = append(this.cycles, timer) } func (this *TransferCommandQ) CanPop(num_items int) bool { if len(this.transfer_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *TransferCommandQ) Pop() *TransferCommand { if !this.CanPop(1) { err := errors.New("transfer command queue cannot be popped") panic(err) } transfer_command := this.transfer_commands[0] this.transfer_commands = this.transfer_commands[1:] this.cycles = this.cycles[1:] return transfer_command } func (this *TransferCommandQ) Front(pos int) (*TransferCommand, int64) { return this.transfer_commands[pos], this.cycles[pos] } func (this *TransferCommandQ) Remove(pos int) { this.transfer_commands = append(this.transfer_commands[:pos], this.transfer_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *TransferCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/bank/wordline.go ================================================ package bank import ( "errors" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Wordline struct { address int64 size int64 byte_stream *encoding.ByteStream } func (this *Wordline) Init(address int64, size int64) { config_loader := new(misc.ConfigLoader) config_loader.Init() mram_data_size := int64(config_loader.MramDataWidth() / 8) if address < 0 { err := errors.New("address < 0") panic(err) } else if size <= 0 { err := errors.New("size <= 0") panic(err) } else if size%mram_data_size != 0 { err := errors.New("size is not aligned with MRAM data size") panic(err) } this.address = address this.size = size this.byte_stream = new(encoding.ByteStream) this.byte_stream.Init() for i := int64(0); i < size; i++ { this.byte_stream.Append(0) } } func (this *Wordline) Fini() { } func (this *Wordline) Read() *encoding.ByteStream { byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < this.byte_stream.Size(); i++ { byte_stream.Append(this.byte_stream.Get(int(i))) } return byte_stream } func (this *Wordline) Write(byte_stream *encoding.ByteStream) { if this.size != byte_stream.Size() { err := errors.New("wordline's size != byte stream's size") panic(err) } for i := int64(0); i < byte_stream.Size(); i++ { this.byte_stream.Set(int(i), byte_stream.Get(int(i))) } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/channel/channel.go ================================================ package channel import ( "errors" "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/host/vm/dram/rank" "uPIMulator/src/misc" ) type Channel struct { channel_id int ranks []*rank.Rank input_q *ChannelCommandQ ready_q *ChannelCommandQ scoreboard map[*rank.RankCommand]*ChannelCommand } func (this *Channel) Init(channel_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } this.channel_id = channel_id this.ranks = make([]*rank.Rank, 0) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) for i := 0; i < num_ranks_per_channel; i++ { rank_ := new(rank.Rank) rank_.Init(channel_id, i, command_line_parser) this.ranks = append(this.ranks, rank_) } this.input_q = new(ChannelCommandQ) this.input_q.Init(-1, 0) this.ready_q = new(ChannelCommandQ) this.ready_q.Init(-1, 0) this.scoreboard = make(map[*rank.RankCommand]*ChannelCommand) } func (this *Channel) Fini() { for _, rank_ := range this.ranks { rank_.Fini() } this.input_q.Fini() this.ready_q.Fini() } func (this *Channel) ChannelId() int { return this.channel_id } func (this *Channel) NumRanks() int { return len(this.ranks) } func (this *Channel) Ranks() []*rank.Rank { return this.ranks } func (this *Channel) Banks() []*bank.Bank { banks := make([]*bank.Bank, 0) for _, rank_ := range this.ranks { banks = append(banks, rank_.Banks()...) } return banks } func (this *Channel) CanPush() bool { return this.input_q.CanPush(1) } func (this *Channel) Push(channel_command *ChannelCommand) { if !this.CanPush() { err := errors.New("channel cannot be pushed") panic(err) } this.input_q.Push(channel_command) } func (this *Channel) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Channel) Pop() *ChannelCommand { if !this.CanPop() { err := errors.New("channel cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Channel) Read(channel_command *ChannelCommand) { rank_id := channel_command.RankId() rank_command := channel_command.RankCommand() this.ranks[rank_id].Read(rank_command) } func (this *Channel) Write(channel_command *ChannelCommand) { rank_id := channel_command.RankId() rank_command := channel_command.RankCommand() this.ranks[rank_id].Write(rank_command) } func (this *Channel) Flush() { for _, rank_ := range this.ranks { rank_.Flush() } } func (this *Channel) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() for _, rank_ := range this.ranks { rank_.Cycle() } this.input_q.Cycle() this.ready_q.Cycle() } func (this *Channel) ServiceInputQ() { if this.input_q.CanPop(1) { channel_command, _ := this.input_q.Front(0) rank_id := channel_command.RankId() if this.ranks[rank_id].CanPush() { this.input_q.Pop() rank_command := channel_command.RankCommand() this.ranks[rank_id].Push(rank_command) this.scoreboard[rank_command] = channel_command } } } func (this *Channel) ServiceReadyQ() { for _, rank_ := range this.ranks { if rank_.CanPop() && this.ready_q.CanPush(1) { rank_command := rank_.Pop() channel_command := this.scoreboard[rank_command] this.ready_q.Push(channel_command) delete(this.scoreboard, rank_command) } } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/channel/channel_command.go ================================================ package channel import ( "errors" "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/host/vm/dram/rank" ) type ChannelCommand struct { channel_id int rank_id int bank_id int rank_command *rank.RankCommand memory_command *bank.MemoryCommand } func (this *ChannelCommand) Init( channel_id int, rank_id int, bank_id int, memory_command *bank.MemoryCommand, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if bank_id < 0 { err := errors.New("DPU ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.bank_id = bank_id this.rank_command = new(rank.RankCommand) this.rank_command.Init(channel_id, rank_id, bank_id, memory_command) this.memory_command = memory_command } func (this *ChannelCommand) ChannelId() int { return this.channel_id } func (this *ChannelCommand) RankId() int { return this.rank_id } func (this *ChannelCommand) BankId() int { return this.bank_id } func (this *ChannelCommand) RankCommand() *rank.RankCommand { return this.rank_command } func (this *ChannelCommand) MemoryCommand() *bank.MemoryCommand { return this.memory_command } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/channel/channel_command_q.go ================================================ package channel import ( "errors" ) type ChannelCommandQ struct { size int timer int64 channel_commands []*ChannelCommand cycles []int64 } func (this *ChannelCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.channel_commands = make([]*ChannelCommand, 0) this.cycles = make([]int64, 0) } func (this *ChannelCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("channel command queue is not empty") panic(err) } } func (this *ChannelCommandQ) Size() int { return this.size } func (this *ChannelCommandQ) Length() int { return len(this.channel_commands) } func (this *ChannelCommandQ) Timer() int64 { return this.timer } func (this *ChannelCommandQ) IsEmpty() bool { return len(this.channel_commands) == 0 } func (this *ChannelCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.channel_commands) >= num_items } else { return true } } func (this *ChannelCommandQ) Push(channel_command *ChannelCommand) { if !this.CanPush(1) { err := errors.New("channel command queue cannot be pushed") panic(err) } this.channel_commands = append(this.channel_commands, channel_command) this.cycles = append(this.cycles, this.timer) } func (this *ChannelCommandQ) PushWithTimer(channel_command *ChannelCommand, timer int64) { if !this.CanPush(1) { err := errors.New("channel command queue cannot be pushed") panic(err) } this.channel_commands = append(this.channel_commands, channel_command) this.cycles = append(this.cycles, timer) } func (this *ChannelCommandQ) CanPop(num_items int) bool { if len(this.channel_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *ChannelCommandQ) Pop() *ChannelCommand { if !this.CanPop(1) { err := errors.New("channel command queue cannot be popped") panic(err) } channel_command := this.channel_commands[0] this.channel_commands = this.channel_commands[1:] this.cycles = this.cycles[1:] return channel_command } func (this *ChannelCommandQ) Front(pos int) (*ChannelCommand, int64) { return this.channel_commands[pos], this.cycles[pos] } func (this *ChannelCommandQ) Remove(pos int) { this.channel_commands = append(this.channel_commands[:pos], this.channel_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *ChannelCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/memory_controller.go ================================================ package dram import ( "errors" "uPIMulator/src/device/simulator/channel" "uPIMulator/src/device/simulator/dpu/dram" "uPIMulator/src/encoding" "uPIMulator/src/host/vm/dram/bank" vm_channel "uPIMulator/src/host/vm/dram/channel" "uPIMulator/src/misc" ) type MemoryController struct { vm_channels []*vm_channel.Channel channels []*channel.Channel memory_scheduler *MemoryScheduler memory_mapping *MemoryMapping input_q *bank.TransferCommandQ vm_dma_command_q *bank.DmaCommandQ vm_channel_command_q *vm_channel.ChannelCommandQ channel_command_q *channel.ChannelCommandQ vm_wait_q *bank.TransferCommandQ scoreboard map[*dram.DmaCommand]*bank.TransferCommand wait_q *bank.TransferCommandQ ready_q *bank.TransferCommandQ } func (this *MemoryController) Init(command_line_parser *misc.CommandLineParser) { num_vm_channels := int(command_line_parser.IntParameter("num_vm_channels")) this.vm_channels = make([]*vm_channel.Channel, 0) for i := 0; i < num_vm_channels; i++ { vm_channel_ := new(vm_channel.Channel) vm_channel_.Init(i, command_line_parser) this.vm_channels = append(this.vm_channels, vm_channel_) } this.memory_scheduler = new(MemoryScheduler) this.memory_scheduler.Init(command_line_parser) this.memory_mapping = new(MemoryMapping) this.memory_mapping.Init(command_line_parser) this.input_q = new(bank.TransferCommandQ) this.input_q.Init(-1, 0) this.vm_dma_command_q = new(bank.DmaCommandQ) this.vm_dma_command_q.Init(-1, 0) this.vm_channel_command_q = new(vm_channel.ChannelCommandQ) this.vm_channel_command_q.Init(-1, 0) this.channel_command_q = new(channel.ChannelCommandQ) this.channel_command_q.Init(-1, 0) this.vm_wait_q = new(bank.TransferCommandQ) this.vm_wait_q.Init(-1, 0) this.scoreboard = make(map[*dram.DmaCommand]*bank.TransferCommand) this.wait_q = new(bank.TransferCommandQ) this.wait_q.Init(-1, 0) this.ready_q = new(bank.TransferCommandQ) this.ready_q.Init(-1, 0) } func (this *MemoryController) Fini() { for _, vm_channel_ := range this.vm_channels { vm_channel_.Fini() } this.memory_scheduler.Fini() this.memory_mapping.Fini() this.input_q.Fini() this.vm_dma_command_q.Fini() this.vm_channel_command_q.Fini() this.channel_command_q.Fini() this.vm_wait_q.Fini() if len(this.scoreboard) != 0 { err := errors.New("scoreboard is not empty") panic(err) } this.wait_q.Fini() this.ready_q.Fini() } func (this *MemoryController) ConnectChannels(channels []*channel.Channel) { this.channels = channels } func (this *MemoryController) VmChannels() []*vm_channel.Channel { return this.vm_channels } func (this *MemoryController) MemoryScheduler() *MemoryScheduler { return this.memory_scheduler } func (this *MemoryController) Banks() []*bank.Bank { banks := make([]*bank.Bank, 0) for _, vm_channel_ := range this.vm_channels { banks = append(banks, vm_channel_.Banks()...) } return banks } func (this *MemoryController) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryController) Push(transfer_command *bank.TransferCommand) { if !this.CanPush() { err := errors.New("memory controller cannot be pushed") panic(err) } this.input_q.Push(transfer_command) } func (this *MemoryController) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryController) Pop() *bank.TransferCommand { if !this.CanPop() { err := errors.New("memory controller cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryController) VmRead(vm_address int64, size int64) *encoding.ByteStream { segments := this.memory_mapping.Map(vm_address, size) transfer_command := new(bank.TransferCommand) transfer_command.InitFast(vm_address, size) for _, segment := range segments { dma_command := new(bank.DmaCommand) dma_command.InitRead(segment, transfer_command) channel_commands := this.memory_scheduler.Generate(dma_command) for _, channel_command := range channel_commands { channel_id := channel_command.ChannelId() this.vm_channels[channel_id].Read(channel_command) } byte_stream := dma_command.ByteStream(segment.BankAddress(), segment.Size()) transfer_command.SetByteStream( dma_command.Segment().VmAddress(), dma_command.Segment().Size(), byte_stream, ) } return transfer_command.ByteStream() } func (this *MemoryController) VmWrite( vm_address int64, size int64, byte_stream *encoding.ByteStream, ) { segments := this.memory_mapping.Map(vm_address, size) transfer_command := new(bank.TransferCommand) transfer_command.InitFast(vm_address, size) transfer_command.SetByteStream(vm_address, size, byte_stream) for _, segment := range segments { dma_command := new(bank.DmaCommand) dma_command.InitWrite(segment, transfer_command) dma_command_byte_stream := new(encoding.ByteStream) dma_command_byte_stream.Init() for i := int64(0); i < dma_command.Segment().Size(); i++ { byte_ := transfer_command.ByteStream().Get(int(segment.VmAddress() + i - vm_address)) dma_command_byte_stream.Append(byte_) } dma_command.SetByteStream(segment.BankAddress(), segment.Size(), dma_command_byte_stream) channel_commands := this.memory_scheduler.Generate(dma_command) for _, channel_command := range channel_commands { channel_id := channel_command.ChannelId() this.vm_channels[channel_id].Write(channel_command) } } } func (this *MemoryController) Flush() { this.memory_scheduler.Flush() for _, vm_channel_ := range this.vm_channels { vm_channel_.Flush() } } func (this *MemoryController) Cycle() { this.ServiceInputQ() this.ServiceVmDmaCommandQ() this.ServiceMemoryScheduler() this.ServiceVmChannelCommandQ() this.ServiceVmChannels() this.ServiceChannelCommandQ() this.ServiceChannels() this.ServiceVmWaitQ() this.ServiceWaitQ() this.memory_scheduler.Cycle() this.input_q.Cycle() this.vm_dma_command_q.Cycle() this.vm_channel_command_q.Cycle() this.channel_command_q.Cycle() this.vm_wait_q.Cycle() this.wait_q.Cycle() this.ready_q.Cycle() for _, channel_ := range this.channels { channel_.Cycle() } } func (this *MemoryController) ServiceInputQ() { // TODO(bongjoon.hyun@gmail.com): need to check if VM DMA queue or channel command queue can be pushed if this.input_q.CanPop(1) { transfer_command := this.input_q.Pop() if transfer_command.TransferCommandType() == bank.HOST_TO_DEVICE { this.vm_wait_q.Push(transfer_command) segments := this.memory_mapping.Map( transfer_command.VmAddress(), transfer_command.Size(), ) for _, segment := range segments { dma_command := new(bank.DmaCommand) dma_command.InitRead(segment, transfer_command) transfer_command.AppendVmDmaCommand(dma_command) this.vm_dma_command_q.Push(dma_command) } } else if transfer_command.TransferCommandType() == bank.DEVICE_TO_HOST { this.wait_q.Push(transfer_command) channel_id := transfer_command.ChannelId() rank_id := transfer_command.RankId() dpu_id := transfer_command.DpuId() mram_address := transfer_command.MramAddress() size := transfer_command.Size() dma_command := new(dram.DmaCommand) dma_command.InitReadFromMram(mram_address, size) this.scoreboard[dma_command] = transfer_command channel_command := new(channel.ChannelCommand) channel_command.Init(channel_id, rank_id, dpu_id, dma_command) transfer_command.AppendDmaCommand(dma_command) this.channel_command_q.Push(channel_command) } else { err := errors.New("transfer command type is not valid") panic(err) } } } func (this *MemoryController) ServiceVmDmaCommandQ() { if this.vm_dma_command_q.CanPop(1) && this.memory_scheduler.CanPush() { dma_command := this.vm_dma_command_q.Pop() this.memory_scheduler.Push(dma_command) } } func (this *MemoryController) ServiceMemoryScheduler() { if this.memory_scheduler.CanPop() && this.vm_channel_command_q.CanPush(1) { vm_channel_command := this.memory_scheduler.Pop() this.vm_channel_command_q.Push(vm_channel_command) } } func (this *MemoryController) ServiceVmChannelCommandQ() { if this.vm_channel_command_q.CanPop(1) { vm_channel_command, _ := this.vm_channel_command_q.Front(0) channel_id := vm_channel_command.ChannelId() if this.vm_channels[channel_id].CanPush() { this.vm_channel_command_q.Pop() this.vm_channels[channel_id].Push(vm_channel_command) } } } func (this *MemoryController) ServiceVmChannels() { for _, vm_channel_ := range this.vm_channels { if vm_channel_.CanPop() { vm_channel_command := vm_channel_.Pop() dma_command := vm_channel_command.MemoryCommand().DmaCommand() transfer_command := dma_command.TransferCommand() if transfer_command.TransferCommandType() == bank.HOST_TO_DEVICE { segment := dma_command.Segment() vm_address := segment.VmAddress() size := segment.Size() byte_stream := dma_command.ByteStream(segment.BankAddress(), segment.Size()) transfer_command.SetByteStream(vm_address, size, byte_stream) if dma_command.IsReady() { transfer_command.AckVmDmaCommand(dma_command) } } else if transfer_command.TransferCommandType() == bank.DEVICE_TO_HOST { if dma_command.IsReady() { transfer_command.AckVmDmaCommand(dma_command) } } else { err := errors.New("transfer command type is not valid") panic(err) } } } } func (this *MemoryController) ServiceChannelCommandQ() { if this.channel_command_q.CanPop(1) { channel_command, _ := this.channel_command_q.Front(0) channel_id := channel_command.ChannelId() if this.channels[channel_id].CanPush() { this.channel_command_q.Pop() this.channels[channel_id].Push(channel_command) } } } func (this *MemoryController) ServiceChannels() { for _, channel_ := range this.channels { if channel_.CanPop() { channel_command := channel_.Pop() dma_command := channel_command.DmaCommand() transfer_command := this.scoreboard[dma_command] delete(this.scoreboard, dma_command) if transfer_command.TransferCommandType() == bank.HOST_TO_DEVICE { if dma_command.IsReady() { transfer_command.AckDmaCommand(dma_command) } } else if transfer_command.TransferCommandType() == bank.DEVICE_TO_HOST { vm_address := transfer_command.VmAddress() size := transfer_command.Size() byte_stream := dma_command.ByteStream(dma_command.MramAddress(), dma_command.Size()) transfer_command.SetByteStream(vm_address, size, byte_stream) if dma_command.IsReady() { transfer_command.AckDmaCommand(dma_command) } } else { err := errors.New("transfer command type is not valid") panic(err) } } } } func (this *MemoryController) ServiceVmWaitQ() { for i := 0; i < this.vm_wait_q.Length(); i++ { transfer_command, _ := this.vm_wait_q.Front(i) if transfer_command.IsVmReady() && transfer_command.IsReady() && transfer_command.TransferCommandState() == bank.MIDDLE && this.ready_q.CanPush(1) { this.vm_wait_q.Remove(i) transfer_command.SetTransferCommandState(bank.END) this.ready_q.Push(transfer_command) } else if transfer_command.IsVmReady() { this.vm_wait_q.Remove(i) transfer_command.SetTransferCommandState(bank.MIDDLE) this.wait_q.Push(transfer_command) channel_id := transfer_command.ChannelId() rank_id := transfer_command.RankId() dpu_id := transfer_command.DpuId() mram_address := transfer_command.MramAddress() size := transfer_command.Size() byte_stream := transfer_command.ByteStream() dma_command := new(dram.DmaCommand) dma_command.InitWriteToMram(mram_address, size, byte_stream) this.scoreboard[dma_command] = transfer_command channel_command := new(channel.ChannelCommand) channel_command.Init(channel_id, rank_id, dpu_id, dma_command) transfer_command.AppendDmaCommand(dma_command) this.channel_command_q.Push(channel_command) } } } func (this *MemoryController) ServiceWaitQ() { for i := 0; i < this.wait_q.Length(); i++ { transfer_command, _ := this.wait_q.Front(i) if transfer_command.IsReady() && transfer_command.IsVmReady() && transfer_command.TransferCommandState() == bank.MIDDLE && this.ready_q.CanPush(1) { this.wait_q.Remove(i) transfer_command.SetTransferCommandState(bank.END) this.ready_q.Push(transfer_command) } else if transfer_command.IsReady() { this.wait_q.Remove(i) transfer_command.SetTransferCommandState(bank.MIDDLE) this.vm_wait_q.Push(transfer_command) segments := this.memory_mapping.Map(transfer_command.VmAddress(), transfer_command.Size()) for _, segment := range segments { dma_command := new(bank.DmaCommand) dma_command.InitWrite(segment, transfer_command) transfer_command.AppendVmDmaCommand(dma_command) this.vm_dma_command_q.Push(dma_command) } } } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/memory_mapping.go ================================================ package dram import ( "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/misc" ) type MemoryMapping struct { num_vm_channels int num_vm_ranks_per_channel int num_vm_banks_per_rank int vm_bg0 int vm_bg1 int vm_bank int vm_bank_offset int64 vm_bank_size int64 } func (this *MemoryMapping) Init(command_line_parser *misc.CommandLineParser) { this.num_vm_channels = int(command_line_parser.IntParameter("num_vm_channels")) this.num_vm_ranks_per_channel = int( command_line_parser.IntParameter("num_vm_ranks_per_channel"), ) this.num_vm_banks_per_rank = int(command_line_parser.IntParameter("num_vm_banks_per_rank")) config_loader := new(misc.ConfigLoader) config_loader.Init() this.vm_bg0 = config_loader.VmBg0() this.vm_bg1 = config_loader.VmBg1() this.vm_bank = config_loader.VmBank() this.vm_bank_offset = config_loader.VmBankOffset() this.vm_bank_size = config_loader.VmBankSize() } func (this *MemoryMapping) Fini() { } func (this *MemoryMapping) Map(vm_address int64, vm_size int64) []*bank.Segment { begin_address := vm_address end_address := vm_address + vm_size segments := make([]*bank.Segment, 0) for address := begin_address; address < end_address; { offset_address := this.OffsetAddress(address) size := this.Min( this.Min( address+this.Offset(), offset_address+this.Offset(), ), end_address, ) - address channel_id := this.ChannelId(address) rank_id := this.RankId(address) bank_id := this.BankId(address) bank_address := this.BankAddress(address) segment := new(bank.Segment) segment.Init(address, channel_id, rank_id, bank_id, bank_address, size) segments = append(segments, segment) address += size } return segments } func (this *MemoryMapping) ChannelId(address int64) int { return int(address / this.ChannelSize()) } func (this *MemoryMapping) RankId(address int64) int { return int((address % this.ChannelSize()) / this.RankSize()) } func (this *MemoryMapping) BankId(address int64) int { return this.Bank(address)*4 + this.Bg1(address)*2 + this.Bg0(address) } func (this *MemoryMapping) BankAddress(address int64) int64 { return address % this.vm_bank_size } func (this *MemoryMapping) ChannelSize() int64 { return int64(this.num_vm_ranks_per_channel) * this.RankSize() } func (this *MemoryMapping) RankSize() int64 { return int64(this.num_vm_banks_per_rank) * this.vm_bank_size } func (this *MemoryMapping) Bg0(address int64) int { return int(address & (1 << this.vm_bg0) >> this.vm_bg0) } func (this *MemoryMapping) Bg1(address int64) int { return int(address & (1 << this.vm_bg1) >> this.vm_bg1) } func (this *MemoryMapping) Bank(address int64) int { return int(address & (3 << this.vm_bank) >> this.vm_bank) } func (this *MemoryMapping) Offset() int64 { return this.Pow2(this.vm_bg0) } func (this *MemoryMapping) OffsetAddress(address int64) int64 { return (address / this.Offset()) * this.Offset() } func (this *MemoryMapping) Pow2(exponent int) int64 { value := int64(1) for i := 0; i < exponent; i++ { value *= 2 } return value } func (this *MemoryMapping) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/memory_scheduler.go ================================================ package dram import ( "errors" "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/host/vm/dram/channel" "uPIMulator/src/misc" ) type MemoryScheduler struct { num_vm_channels int num_vm_ranks_per_channel int num_vm_banks_per_rank int input_q *bank.DmaCommandQ reorder_buffer *channel.ChannelCommandQ ready_q *channel.ChannelCommandQ row_addresses map[int]int64 wordline_size int64 min_access_granularity int64 reorder_window_size int stat_factory *misc.StatFactory } func (this *MemoryScheduler) Init(command_line_parser *misc.CommandLineParser) { this.num_vm_channels = int(command_line_parser.IntParameter("num_vm_channels")) this.num_vm_ranks_per_channel = int( command_line_parser.IntParameter("num_vm_ranks_per_channel"), ) this.num_vm_banks_per_rank = int(command_line_parser.IntParameter("num_vm_banks_per_rank")) this.input_q = new(bank.DmaCommandQ) this.input_q.Init(-1, 0) this.reorder_buffer = new(channel.ChannelCommandQ) this.reorder_buffer.Init(-1, 0) this.ready_q = new(channel.ChannelCommandQ) this.ready_q.Init(-1, 0) this.row_addresses = make(map[int]int64) this.wordline_size = command_line_parser.IntParameter("wordline_size") this.min_access_granularity = command_line_parser.IntParameter("min_access_granularity") this.reorder_window_size = int(command_line_parser.IntParameter("reorder_window_size")) this.stat_factory = new(misc.StatFactory) this.stat_factory.Init("MemoryScheduler") } func (this *MemoryScheduler) Fini() { this.input_q.Fini() this.reorder_buffer.Fini() this.ready_q.Fini() } func (this *MemoryScheduler) StatFactory() *misc.StatFactory { return this.stat_factory } func (this *MemoryScheduler) IsEmpty() bool { return this.input_q.IsEmpty() && this.reorder_buffer.IsEmpty() && this.ready_q.IsEmpty() } func (this *MemoryScheduler) CanPush() bool { return this.input_q.CanPush(1) } func (this *MemoryScheduler) Push(dma_command *bank.DmaCommand) { if !this.CanPush() { err := errors.New("memory scheduler cannot be pushed") panic(err) } this.input_q.Push(dma_command) } func (this *MemoryScheduler) CanPop() bool { return this.ready_q.CanPop(1) } func (this *MemoryScheduler) Pop() *channel.ChannelCommand { if !this.CanPop() { err := errors.New("memory scheduler cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *MemoryScheduler) Generate(dma_command *bank.DmaCommand) []*channel.ChannelCommand { begin_address := dma_command.Segment().BankAddress() end_address := dma_command.Segment().BankAddress() + dma_command.Segment().Size() channel_commands := make([]*channel.ChannelCommand, 0) for address := begin_address; address < end_address; { wordline_address := this.WordlineAddress(address) size := this.Min( this.Min( address+this.min_access_granularity, wordline_address+this.wordline_size, ), end_address, ) - address memory_operation := dma_command.MemoryOperation() memory_command := new(bank.MemoryCommand) if memory_operation == bank.READ { memory_command.InitRead(bank.READ, address, size, dma_command) } else if memory_operation == bank.WRITE { byte_stream := dma_command.ByteStream(address, size) memory_command.InitWrite(bank.WRITE, address, size, byte_stream, dma_command) } else { err := errors.New("memory operation is not valid") panic(err) } channel_command := new(channel.ChannelCommand) channel_command.Init( dma_command.Segment().ChannelID(), dma_command.Segment().RankID(), dma_command.Segment().BankID(), memory_command, ) channel_commands = append(channel_commands, channel_command) address += size } return channel_commands } func (this *MemoryScheduler) Flush() { if !this.IsEmpty() { err := errors.New("memory scheduler cannot be flushed") panic(err) } this.row_addresses = make(map[int]int64) } func (this *MemoryScheduler) Cycle() { this.ServiceInputQ() if !this.ReorderFr() { this.ReorderFcFs() } this.input_q.Cycle() this.reorder_buffer.Cycle() this.ready_q.Cycle() } func (this *MemoryScheduler) ServiceInputQ() { if this.input_q.CanPop(1) { dma_command := this.input_q.Pop() this.PopulateMemoryCommands(dma_command) } } func (this *MemoryScheduler) PopulateMemoryCommands(dma_command *bank.DmaCommand) { begin_address := dma_command.Segment().BankAddress() end_address := dma_command.Segment().BankAddress() + dma_command.Segment().Size() for address := begin_address; address < end_address; { wordline_address := this.WordlineAddress(address) size := this.Min( this.Min( address+this.min_access_granularity, wordline_address+this.wordline_size, ), end_address, ) - address memory_operation := dma_command.MemoryOperation() memory_command := new(bank.MemoryCommand) if memory_operation == bank.READ { memory_command.InitRead(bank.READ, address, size, dma_command) } else if memory_operation == bank.WRITE { byte_stream := dma_command.ByteStream(address, size) memory_command.InitWrite(bank.WRITE, address, size, byte_stream, dma_command) } else { err := errors.New("memory operation is not valid") panic(err) } channel_command := new(channel.ChannelCommand) channel_command.Init( dma_command.Segment().ChannelID(), dma_command.Segment().RankID(), dma_command.Segment().BankID(), memory_command, ) this.reorder_buffer.Push(channel_command) address += size } } func (this *MemoryScheduler) ReorderFr() bool { if this.ready_q.CanPush(1) { for i := 0; this.reorder_buffer.CanPop(i+1) && i < this.reorder_window_size; i++ { channel_command, _ := this.reorder_buffer.Front(i) memory_command := channel_command.MemoryCommand() wordline_address := this.WordlineAddress(memory_command.BankAddress()) if this.IsOpened(channel_command) && this.RowAddress(channel_command) == wordline_address { if i != 0 { this.stat_factory.Increment("num_fr", 1) } else { this.stat_factory.Increment("num_fcfs", 1) } this.reorder_buffer.Remove(i) this.ready_q.Push(channel_command) return true } } } return false } func (this *MemoryScheduler) ReorderFcFs() bool { if this.reorder_buffer.CanPop(1) && this.ready_q.CanPush(3) { channel_command, _ := this.reorder_buffer.Front(0) if this.IsOpened(channel_command) { this.reorder_buffer.Remove(0) memory_command := channel_command.MemoryCommand() wordline_address := this.WordlineAddress(memory_command.BankAddress()) precharge := new(bank.MemoryCommand) precharge.InitActivation(bank.PRECHARGE, this.RowAddress(channel_command)) activation := new(bank.MemoryCommand) activation.InitActivation(bank.ACTIVATION, wordline_address) channel_id := channel_command.ChannelId() rank_id := channel_command.RankId() bank_id := channel_command.BankId() precharge_channel_command := new(channel.ChannelCommand) precharge_channel_command.Init(channel_id, rank_id, bank_id, precharge) activation_channel_command := new(channel.ChannelCommand) activation_channel_command.Init(channel_id, rank_id, bank_id, activation) this.ready_q.Push(precharge_channel_command) this.ready_q.Push(activation_channel_command) this.ready_q.Push(channel_command) this.row_addresses[this.UniqueBankId(channel_id, rank_id, bank_id)] = wordline_address return true } else { this.reorder_buffer.Remove(0) memory_command := channel_command.MemoryCommand() wordline_address := this.WordlineAddress(memory_command.BankAddress()) activation := new(bank.MemoryCommand) activation.InitActivation(bank.ACTIVATION, wordline_address) channel_id := channel_command.ChannelId() rank_id := channel_command.RankId() bank_id := channel_command.BankId() activation_channel_command := new(channel.ChannelCommand) activation_channel_command.Init(channel_id, rank_id, bank_id, activation) this.ready_q.Push(activation_channel_command) this.ready_q.Push(channel_command) this.row_addresses[this.UniqueBankId(channel_id, rank_id, bank_id)] = wordline_address return true } } else { return false } } func (this *MemoryScheduler) IsOpened(channel_command *channel.ChannelCommand) bool { unique_bank_id := this.UniqueBankId( channel_command.ChannelId(), channel_command.RankId(), channel_command.BankId(), ) if _, found := this.row_addresses[unique_bank_id]; found { return true } else { return false } } func (this *MemoryScheduler) RowAddress(channel_command *channel.ChannelCommand) int64 { unique_bank_id := this.UniqueBankId( channel_command.ChannelId(), channel_command.RankId(), channel_command.BankId(), ) if row_address, found := this.row_addresses[unique_bank_id]; found { return row_address } else { err := errors.New("unique bank is not opened") panic(err) } } func (this *MemoryScheduler) UniqueBankId(channel_id int, rank_id int, bank_id int) int { return channel_id*this.num_vm_ranks_per_channel*this.num_vm_banks_per_rank + rank_id*this.num_vm_banks_per_rank + bank_id } func (this *MemoryScheduler) WordlineAddress(address int64) int64 { return address / this.wordline_size * this.wordline_size } func (this *MemoryScheduler) Min(x int64, y int64) int64 { if x <= y { return x } else { return y } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/rank/rank.go ================================================ package rank import ( "errors" "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/misc" ) type Rank struct { channel_id int rank_id int banks []*bank.Bank input_q *RankCommandQ ready_q *RankCommandQ scoreboard map[*bank.MemoryCommand]*RankCommand } func (this *Rank) Init(channel_id int, rank_id int, command_line_parser *misc.CommandLineParser) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.banks = make([]*bank.Bank, 0) num_vm_banks_per_rank := int(command_line_parser.IntParameter("num_vm_banks_per_rank")) for i := 0; i < num_vm_banks_per_rank; i++ { bank_ := new(bank.Bank) bank_.Init(channel_id, rank_id, i, command_line_parser) this.banks = append(this.banks, bank_) } this.input_q = new(RankCommandQ) this.input_q.Init(-1, 0) this.ready_q = new(RankCommandQ) this.ready_q.Init(-1, 0) this.scoreboard = make(map[*bank.MemoryCommand]*RankCommand) } func (this *Rank) Fini() { for _, bank_ := range this.banks { bank_.Fini() } this.input_q.Fini() this.ready_q.Fini() } func (this *Rank) ChannelID() int { return this.channel_id } func (this *Rank) RankId() int { return this.rank_id } func (this *Rank) NumBanks() int { return len(this.banks) } func (this *Rank) Banks() []*bank.Bank { return this.banks } func (this *Rank) CanPush() bool { return this.input_q.CanPush(1) } func (this *Rank) Push(rank_command *RankCommand) { if !this.CanPush() { err := errors.New("rank cannot be pushed") panic(err) } this.input_q.Push(rank_command) } func (this *Rank) CanPop() bool { return this.ready_q.CanPop(1) } func (this *Rank) Pop() *RankCommand { if !this.CanPop() { err := errors.New("rank cannot be popped") panic(err) } return this.ready_q.Pop() } func (this *Rank) Read(rank_command *RankCommand) { bank_id := rank_command.BankId() memory_command := rank_command.MemoryCommand() bank_address := memory_command.BankAddress() size := memory_command.Size() byte_stream := this.banks[bank_id].Read(bank_address, size) memory_command.SetByteStream(byte_stream) } func (this *Rank) Write(rank_command *RankCommand) { bank_id := rank_command.BankId() memory_command := rank_command.MemoryCommand() bank_address := memory_command.BankAddress() size := memory_command.Size() byte_stream := memory_command.ByteStream() this.banks[bank_id].Write(bank_address, size, byte_stream) } func (this *Rank) Flush() { for _, bank_ := range this.banks { bank_.Flush() } } func (this *Rank) Cycle() { this.ServiceInputQ() this.ServiceReadyQ() this.input_q.Cycle() this.ready_q.Cycle() } func (this *Rank) ServiceInputQ() { if this.input_q.CanPop(1) { rank_command, _ := this.input_q.Front(0) bank_id := rank_command.BankId() if this.banks[bank_id].CanPush() { this.input_q.Pop() memory_command := rank_command.MemoryCommand() this.banks[bank_id].Push(memory_command) this.scoreboard[memory_command] = rank_command } } } func (this *Rank) ServiceReadyQ() { for _, bank_ := range this.banks { if bank_.CanPop() && this.ready_q.CanPush(1) { memory_command := bank_.Pop() rank_command := this.scoreboard[memory_command] this.ready_q.Push(rank_command) delete(this.scoreboard, memory_command) } } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/rank/rank_command.go ================================================ package rank import ( "errors" "uPIMulator/src/host/vm/dram/bank" ) type RankCommand struct { channel_id int rank_id int bank_id int memory_command *bank.MemoryCommand } func (this *RankCommand) Init( channel_id int, rank_id int, bank_id int, memory_command *bank.MemoryCommand, ) { if channel_id < 0 { err := errors.New("channel ID < 0") panic(err) } else if rank_id < 0 { err := errors.New("rank ID < 0") panic(err) } else if bank_id < 0 { err := errors.New("bank ID < 0") panic(err) } this.channel_id = channel_id this.rank_id = rank_id this.bank_id = bank_id this.memory_command = memory_command } func (this *RankCommand) ChannelId() int { return this.channel_id } func (this *RankCommand) RankId() int { return this.rank_id } func (this *RankCommand) BankId() int { return this.bank_id } func (this *RankCommand) MemoryCommand() *bank.MemoryCommand { return this.memory_command } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/dram/rank/rank_command_q.go ================================================ package rank import ( "errors" ) type RankCommandQ struct { size int timer int64 rank_commands []*RankCommand cycles []int64 } func (this *RankCommandQ) Init(size int, timer int64) { if size == 0 { err := errors.New("size == 0") panic(err) } else if timer < 0 { err := errors.New("timer < 0") panic(err) } this.size = size this.timer = timer this.rank_commands = make([]*RankCommand, 0) this.cycles = make([]int64, 0) } func (this *RankCommandQ) Fini() { if !this.IsEmpty() { err := errors.New("rank command queue is not empty") panic(err) } } func (this *RankCommandQ) Size() int { return this.size } func (this *RankCommandQ) Length() int { return len(this.rank_commands) } func (this *RankCommandQ) Timer() int64 { return this.timer } func (this *RankCommandQ) IsEmpty() bool { return len(this.rank_commands) == 0 } func (this *RankCommandQ) CanPush(num_items int) bool { if this.size >= 0 { return this.size-len(this.rank_commands) >= num_items } else { return true } } func (this *RankCommandQ) Push(rank_command *RankCommand) { if !this.CanPush(1) { err := errors.New("rank command queue cannot be pushed") panic(err) } this.rank_commands = append(this.rank_commands, rank_command) this.cycles = append(this.cycles, this.timer) } func (this *RankCommandQ) PushWithTimer(rank_command *RankCommand, timer int64) { if !this.CanPush(1) { err := errors.New("rank command queue cannot be pushed") panic(err) } this.rank_commands = append(this.rank_commands, rank_command) this.cycles = append(this.cycles, timer) } func (this *RankCommandQ) CanPop(num_items int) bool { if len(this.rank_commands) < num_items { return false } else { for i := 0; i < num_items; i++ { cycle := this.cycles[i] if cycle > 0 { return false } } return true } } func (this *RankCommandQ) Pop() *RankCommand { if !this.CanPop(1) { err := errors.New("rank command queue cannot be popped") panic(err) } rank_command := this.rank_commands[0] this.rank_commands = this.rank_commands[1:] this.cycles = this.cycles[1:] return rank_command } func (this *RankCommandQ) Front(pos int) (*RankCommand, int64) { return this.rank_commands[pos], this.cycles[pos] } func (this *RankCommandQ) Remove(pos int) { this.rank_commands = append(this.rank_commands[:pos], this.rank_commands[pos+1:]...) this.cycles = append(this.cycles[:pos], this.cycles[pos+1:]...) } func (this *RankCommandQ) Cycle() { if !this.IsEmpty() { this.cycles[0] -= 1 } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/frame/frame.go ================================================ package frame import ( "uPIMulator/src/host/abi" "uPIMulator/src/host/vm/pc" "uPIMulator/src/host/vm/stack" "uPIMulator/src/host/vm/symbol" ) type Frame struct { stack *stack.Stack return_stack *stack.ReturnStack fast_scope_chain *symbol.ScopeChain arg_scope *symbol.Scope pc *pc.Pc } func (this *Frame) Init(label *abi.Label) { this.stack = new(stack.Stack) this.stack.Init() this.return_stack = new(stack.ReturnStack) this.return_stack.Init() this.fast_scope_chain = new(symbol.ScopeChain) this.fast_scope_chain.Init() this.arg_scope = new(symbol.Scope) this.arg_scope.Init() this.pc = new(pc.Pc) this.pc.Init() this.pc.Jump(label) } func (this *Frame) Stack() *stack.Stack { return this.stack } func (this *Frame) ReturnStack() *stack.ReturnStack { return this.return_stack } func (this *Frame) FastScopeChain() *symbol.ScopeChain { return this.fast_scope_chain } func (this *Frame) ArgScope() *symbol.Scope { return this.arg_scope } func (this *Frame) Pc() *pc.Pc { return this.pc } func (this *Frame) Symbols() []*symbol.Symbol { symbols := make([]*symbol.Symbol, 0) symbols = append(symbols, this.fast_scope_chain.Symbols()...) symbols = append(symbols, this.arg_scope.Symbols()...) return symbols } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/frame/frame_chain.go ================================================ package frame import ( "errors" "uPIMulator/src/host/abi" "uPIMulator/src/host/vm/symbol" ) type FrameChain struct { global_scope *symbol.Scope frames []*Frame } func (this *FrameChain) Init() { this.global_scope = new(symbol.Scope) this.global_scope.Init() this.frames = make([]*Frame, 0) } func (this *FrameChain) Bootstrap(label *abi.Label) { frame := new(Frame) frame.Init(label) this.frames = append(this.frames, frame) } func (this *FrameChain) GlobalScope() *symbol.Scope { return this.global_scope } func (this *FrameChain) Length() int { return len(this.frames) } func (this *FrameChain) Symbols() []*symbol.Symbol { symbols := make([]*symbol.Symbol, 0) symbols = append(symbols, this.global_scope.Symbols()...) for _, frame := range this.frames { symbols = append(symbols, frame.Symbols()...) } return symbols } func (this *FrameChain) HasObject(address int64) bool { for _, frame := range this.frames { if frame.Stack().HasObject(address) || frame.ReturnStack().HasObject(address) { return true } } return false } func (this *FrameChain) NewFrame(label *abi.Label) { frame := new(Frame) frame.Init(label) frame.FastScopeChain().NewScope() for _, symbol_ := range this.LastFrame().ArgScope().Symbols() { frame.FastScopeChain().AddSymbol(symbol_) } this.LastFrame().ArgScope().Clear() this.frames = append(this.frames, frame) } func (this *FrameChain) DeleteFrame() { last_frame := this.LastFrame() if len(this.frames) >= 2 { for i := 0; i < last_frame.ReturnStack().Length(); i++ { stack_item := last_frame.ReturnStack().Front(0) last_frame.ReturnStack().Pop() this.frames[len(this.frames)-2].Stack().Push(stack_item) } } this.frames = this.frames[:len(this.frames)-1] } func (this *FrameChain) Frame(pos int) *Frame { return this.frames[pos] } func (this *FrameChain) LastFrame() *Frame { return this.frames[len(this.frames)-1] } func (this *FrameChain) CanAdvance() bool { for this.Length() > 0 { last_frame := this.LastFrame() if last_frame.Pc().CanAdvance() { return true } else { this.DeleteFrame() } } return false } func (this *FrameChain) Advance() *abi.Bytecode { if !this.CanAdvance() { err := errors.New("frame chain cannot advance") panic(err) } return this.LastFrame().Pc().Advance() } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/pc/pc.go ================================================ package pc import ( "uPIMulator/src/host/abi" ) type Pc struct { label *abi.Label index int } func (this *Pc) Init() { this.label = nil this.index = 0 } func (this *Pc) CanAdvance() bool { return this.index < this.label.Length() } func (this *Pc) Advance() *abi.Bytecode { bytecode := this.label.Get(this.index) this.index++ return bytecode } func (this *Pc) Jump(label *abi.Label) { this.label = label this.index = 0 } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/stack/return_stack.go ================================================ package stack type ReturnStack struct { stack_items []*StackItem } func (this *ReturnStack) Init() { this.stack_items = make([]*StackItem, 0) } func (this *ReturnStack) Front(pos int) *StackItem { return this.stack_items[len(this.stack_items)-1-pos] } func (this *ReturnStack) Push(stack_item *StackItem) { this.stack_items = append(this.stack_items, stack_item) } func (this *ReturnStack) Pop() { this.stack_items = this.stack_items[:len(this.stack_items)-1] } func (this *ReturnStack) HasObject(address int64) bool { for _, stack_item := range this.stack_items { if stack_item.Address() == address { return true } } return false } func (this *ReturnStack) Length() int { return len(this.stack_items) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/stack/stack.go ================================================ package stack type Stack struct { stack_items []*StackItem } func (this *Stack) Init() { this.stack_items = make([]*StackItem, 0) } func (this *Stack) Front(pos int) *StackItem { return this.stack_items[len(this.stack_items)-1-pos] } func (this *Stack) Push(stack_item *StackItem) { this.stack_items = append(this.stack_items, stack_item) } func (this *Stack) Pop() { this.stack_items = this.stack_items[:len(this.stack_items)-1] } func (this *Stack) HasObject(address int64) bool { for _, stack_item := range this.stack_items { if stack_item.Address() == address { return true } } return false } func (this *Stack) Length() int { return len(this.stack_items) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/stack/stack_item.go ================================================ package stack import ( "uPIMulator/src/host/vm/type_system" ) type StackItem struct { type_variable *type_system.TypeVariable address int64 size int64 } func (this *StackItem) Init(type_variable *type_system.TypeVariable, address int64, size int64) { this.type_variable = type_variable this.address = address this.size = size } func (this *StackItem) TypeVariable() *type_system.TypeVariable { return this.type_variable } func (this *StackItem) Address() int64 { return this.address } func (this *StackItem) Size() int64 { return this.size } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/symbol/scope.go ================================================ package symbol import ( "errors" "fmt" ) type Scope struct { symbols map[string]*Symbol } func (this *Scope) Init() { this.symbols = make(map[string]*Symbol) } func (this *Scope) HasSymbol(symbol_name string) bool { _, found := this.symbols[symbol_name] return found } func (this *Scope) Symbol(symbol_name string) *Symbol { if !this.HasSymbol(symbol_name) { err_msg := fmt.Sprintf("symbol (%s) is not found", symbol_name) err := errors.New(err_msg) panic(err) } return this.symbols[symbol_name] } func (this *Scope) Symbols() []*Symbol { symbols := make([]*Symbol, 0) for _, symbol := range this.symbols { symbols = append(symbols, symbol) } return symbols } func (this *Scope) AddSymbol(symbol *Symbol) { if this.HasSymbol(symbol.Name()) { err_msg := fmt.Sprintf("symbol (%s) already exists", symbol.Name()) err := errors.New(err_msg) panic(err) } this.symbols[symbol.Name()] = symbol } func (this *Scope) HasObject(address int64) bool { for _, symbol := range this.symbols { if symbol.Object().Address() == address { return true } } return false } func (this *Scope) Clear() { this.symbols = make(map[string]*Symbol) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/symbol/scope_chain.go ================================================ package symbol import ( "errors" "fmt" ) type ScopeChain struct { scopes []*Scope } func (this *ScopeChain) Init() { this.scopes = make([]*Scope, 0) } func (this *ScopeChain) NewScope() { scope := new(Scope) scope.Init() this.scopes = append(this.scopes, scope) } func (this *ScopeChain) DeleteScope() { this.scopes = this.scopes[:len(this.scopes)-1] } func (this *ScopeChain) LastScope() *Scope { return this.scopes[len(this.scopes)-1] } func (this *ScopeChain) HasSymbol(symbol_name string) bool { for i := len(this.scopes) - 1; i >= 0; i-- { scope := this.scopes[i] if scope.HasSymbol(symbol_name) { return true } } return false } func (this *ScopeChain) Symbol(symbol_name string) *Symbol { if !this.HasSymbol(symbol_name) { err_msg := fmt.Sprintf("symbol (%s) is not found", symbol_name) err := errors.New(err_msg) panic(err) } for i := len(this.scopes) - 1; i >= 0; i-- { scope := this.scopes[i] if scope.HasSymbol(symbol_name) { return scope.Symbol(symbol_name) } } return nil } func (this *ScopeChain) Symbols() []*Symbol { symbols := make([]*Symbol, 0) for i := 0; i < len(this.scopes); i++ { scope := this.scopes[i] symbols = append(symbols, scope.Symbols()...) } return symbols } func (this *ScopeChain) AddSymbol(symbol *Symbol) { if this.scopes[len(this.scopes)-1].HasSymbol(symbol.Name()) { err_msg := fmt.Sprintf("symbol (%s) already exists", symbol.Name()) err := errors.New(err_msg) panic(err) } scope := this.scopes[len(this.scopes)-1] scope.AddSymbol(symbol) } func (this *ScopeChain) HasObject(address int64) bool { for _, scope := range this.scopes { if scope.HasObject(address) { return true } } return false } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/symbol/symbol.go ================================================ package symbol import ( "uPIMulator/src/host/vm/base" "uPIMulator/src/host/vm/type_system" ) type Symbol struct { name string type_variable *type_system.TypeVariable object *base.Object } func (this *Symbol) Init( name string, type_variable *type_system.TypeVariable, object *base.Object, ) { this.name = name this.type_variable = type_variable this.object = object } func (this *Symbol) Name() string { return this.name } func (this *Symbol) TypeVariable() *type_system.TypeVariable { return this.type_variable } func (this *Symbol) Object() *base.Object { return this.object } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/type_system/field.go ================================================ package type_system type Field struct { type_variable *TypeVariable name string } func (this *Field) Init(type_variable *TypeVariable, name string) { this.type_variable = type_variable this.name = name } func (this *Field) TypeVariable() *TypeVariable { return this.type_variable } func (this *Field) Name() string { return this.name } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/type_system/registry.go ================================================ package type_system import ( "errors" "fmt" ) type TypeRegistry struct { skeletons map[string]*Skeleton } func (this *TypeRegistry) Init() { this.skeletons = make(map[string]*Skeleton) } func (this *TypeRegistry) HasSkeleton(skeleton_name string) bool { _, found := this.skeletons[skeleton_name] return found } func (this *TypeRegistry) Skeleton(skeleton_name string) *Skeleton { if !this.HasSkeleton(skeleton_name) { err_msg := fmt.Sprintf("skeleton (%s) is not found", skeleton_name) err := errors.New(err_msg) panic(err) } return this.skeletons[skeleton_name] } func (this *TypeRegistry) AddSkeleton(skeleton *Skeleton) { if this.HasSkeleton(skeleton.Name()) { err_msg := fmt.Sprintf("skeleton (%s) already exists", skeleton.Name()) err := errors.New(err_msg) panic(err) } this.skeletons[skeleton.Name()] = skeleton } func (this *TypeRegistry) SkeletonSize(skeleton_name string) int64 { if !this.HasSkeleton(skeleton_name) { err_msg := fmt.Sprintf("skeleton (%s) is not found", skeleton_name) err := errors.New(err_msg) panic(err) } skeleton := this.Skeleton(skeleton_name) offset := int64(0) for i := 0; i < skeleton.Length(); i++ { field := skeleton.Get(i) if field.TypeVariable().NumStars() > 0 { offset += 4 } else { if field.TypeVariable().TypeVariableType() == VOID { err := errors.New("type variable type is void") panic(err) } else if field.TypeVariable().TypeVariableType() == CHAR { offset += 1 } else if field.TypeVariable().TypeVariableType() == SHORT { offset += 2 } else if field.TypeVariable().TypeVariableType() == INT { offset += 4 } else if field.TypeVariable().TypeVariableType() == LONG { offset += 8 } else if field.TypeVariable().TypeVariableType() == STRUCT { offset += this.SkeletonSize(field.TypeVariable().StructName()) } } } return offset } func (this *TypeRegistry) FieldOffset(skeleton_name string, field_name string) int64 { if !this.HasSkeleton(skeleton_name) { err_msg := fmt.Sprintf("skeleton (%s) is not found", skeleton_name) err := errors.New(err_msg) panic(err) } skeleton := this.Skeleton(skeleton_name) offset := int64(0) for i := 0; i < skeleton.Length(); i++ { field := skeleton.Get(i) if field.Name() == field_name { break } if field.TypeVariable().NumStars() > 0 { offset += 4 } else { if field.TypeVariable().TypeVariableType() == VOID { err := errors.New("type variable type is void") panic(err) } else if field.TypeVariable().TypeVariableType() == CHAR { offset += 1 } else if field.TypeVariable().TypeVariableType() == SHORT { offset += 2 } else if field.TypeVariable().TypeVariableType() == INT { offset += 4 } else if field.TypeVariable().TypeVariableType() == LONG { offset += 8 } else if field.TypeVariable().TypeVariableType() == STRUCT { offset += this.SkeletonSize(field.TypeVariable().StructName()) } else { err := errors.New("type variable type is not valid") panic(err) } } } return offset } func (this *TypeRegistry) FieldSize(skeleton_name string, field_name string) int64 { if !this.HasSkeleton(skeleton_name) { err_msg := fmt.Sprintf("skeleton (%s) is not found", skeleton_name) err := errors.New(err_msg) panic(err) } skeleton := this.Skeleton(skeleton_name) field := skeleton.Field(field_name) if field.TypeVariable().NumStars() > 0 { return 4 } else { if field.TypeVariable().TypeVariableType() == VOID { err := errors.New("type variable type is void") panic(err) } else if field.TypeVariable().TypeVariableType() == CHAR { return 1 } else if field.TypeVariable().TypeVariableType() == SHORT { return 2 } else if field.TypeVariable().TypeVariableType() == INT { return 4 } else if field.TypeVariable().TypeVariableType() == LONG { return 8 } else if field.TypeVariable().TypeVariableType() == STRUCT { return this.SkeletonSize(field.TypeVariable().StructName()) } else { err := errors.New("type variable type is not valid") panic(err) } } } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/type_system/skeleton.go ================================================ package type_system import ( "errors" "fmt" ) type Skeleton struct { name string fields []*Field } func (this *Skeleton) Init(name string) { this.name = name } func (this *Skeleton) Name() string { return this.name } func (this *Skeleton) HasField(field_name string) bool { for _, field := range this.fields { if field.Name() == field_name { return true } } return false } func (this *Skeleton) Field(field_name string) *Field { if !this.HasField(field_name) { err_msg := fmt.Sprintf("skeleton (%s) does not have the field (%s)", this.name, field_name) err := errors.New(err_msg) panic(err) } for _, field := range this.fields { if field.Name() == field_name { return field } } return nil } func (this *Skeleton) Fields() []*Field { return this.fields } func (this *Skeleton) Length() int { return len(this.fields) } func (this *Skeleton) Get(pos int) *Field { return this.fields[pos] } func (this *Skeleton) Append(field *Field) { this.fields = append(this.fields, field) } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/type_system/type_variable.go ================================================ package type_system import ( "errors" ) type TypeVariableType int const ( VOID TypeVariableType = iota CHAR SHORT INT LONG STRING STRUCT ) type TypeVariable struct { type_variable_type TypeVariableType struct_name *string num_stars int } func (this *TypeVariable) InitPrimitive(type_variable_type TypeVariableType, num_stars int) { if type_variable_type == STRUCT { err := errors.New("type variable type is struct") panic(err) } this.type_variable_type = type_variable_type this.struct_name = nil this.num_stars = num_stars } func (this *TypeVariable) InitStruct( type_variable_type TypeVariableType, struct_name string, num_stars int, ) { if type_variable_type != STRUCT { err := errors.New("type variable type isn't struct") panic(err) } this.type_variable_type = type_variable_type this.struct_name = new(string) *this.struct_name = struct_name this.num_stars = num_stars } func (this *TypeVariable) TypeVariableType() TypeVariableType { return this.type_variable_type } func (this *TypeVariable) StructName() string { if this.struct_name == nil { err := errors.New("struct name == nil") panic(err) } return *this.struct_name } func (this *TypeVariable) NumStars() int { return this.num_stars } ================================================ FILE: golang_vm/uPIMulator/src/host/vm/virtual_machine.go ================================================ package vm import ( "errors" "fmt" "math" "path/filepath" "uPIMulator/src/device/core" "uPIMulator/src/device/simulator/channel" "uPIMulator/src/device/simulator/dpu" "uPIMulator/src/encoding" "uPIMulator/src/host/abi" "uPIMulator/src/host/vm/arena" "uPIMulator/src/host/vm/base" "uPIMulator/src/host/vm/dram" "uPIMulator/src/host/vm/dram/bank" "uPIMulator/src/host/vm/frame" "uPIMulator/src/host/vm/stack" "uPIMulator/src/host/vm/symbol" "uPIMulator/src/host/vm/type_system" "uPIMulator/src/misc" "uPIMulator/src/program" ) type VirtualMachine struct { bin_dirpath string num_channels int num_ranks_per_channel int num_dpus_per_rank int num_dpus int verbose int app *program.App task *program.Task arena *arena.Arena frame_chain *frame.FrameChain type_registry *type_system.TypeRegistry garbage_collector *arena.GarbageCollector cur_skeleton_name *string memory_controller *dram.MemoryController channels []*channel.Channel prepare_xfer_buf map[*dpu.Dpu]int64 push_xfer map[*bank.TransferCommand]bool } func (this *VirtualMachine) Init(command_line_parser *misc.CommandLineParser) { this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.num_channels = int(command_line_parser.IntParameter("num_channels")) this.num_ranks_per_channel = int(command_line_parser.IntParameter("num_ranks_per_channel")) this.num_dpus_per_rank = int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_dpus = this.num_channels * this.num_ranks_per_channel * this.num_dpus_per_rank this.verbose = int(command_line_parser.IntParameter("verbose")) this.app = nil this.task = nil this.arena = new(arena.Arena) this.arena.Init() this.frame_chain = new(frame.FrameChain) this.frame_chain.Init() this.type_registry = new(type_system.TypeRegistry) this.type_registry.Init() this.garbage_collector = new(arena.GarbageCollector) this.garbage_collector.Init() this.garbage_collector.ConnectArena(this.arena) this.garbage_collector.ConnectFrameChain(this.frame_chain) this.garbage_collector.ConnectRegistry(this.type_registry) this.cur_skeleton_name = nil this.memory_controller = new(dram.MemoryController) this.memory_controller.Init(command_line_parser) this.channels = make([]*channel.Channel, 0) for i := 0; i < this.num_channels; i++ { channel_ := new(channel.Channel) channel_.Init(i, command_line_parser) this.channels = append(this.channels, channel_) } this.memory_controller.ConnectChannels(this.channels) this.prepare_xfer_buf = make(map[*dpu.Dpu]int64) this.push_xfer = make(map[*bank.TransferCommand]bool) } func (this *VirtualMachine) Fini() { for _, channel_ := range this.channels { channel_.Fini() } this.memory_controller.Fini() if len(this.prepare_xfer_buf) != 0 { err := errors.New("VM's prepare xfer buf is not empty") panic(err) } } func (this *VirtualMachine) Load(app *program.App, task *program.Task) { this.app = app this.task = task bootstrap := this.app.Label("__bootstrap") this.frame_chain.Bootstrap(bootstrap) } func (this *VirtualMachine) CanAdvance() bool { return this.frame_chain.CanAdvance() } func (this *VirtualMachine) Advance() { if !this.frame_chain.CanAdvance() { err := errors.New("frame chain cannot advance") panic(err) } this.garbage_collector.MarkAndSweep() bytecode := this.frame_chain.Advance() if this.verbose >= 1 { fmt.Printf("%s\n", bytecode.Stringify()) } if bytecode.OpCode() == abi.NEW_SCOPE { this.frame_chain.LastFrame().FastScopeChain().NewScope() } else if bytecode.OpCode() == abi.DELETE_SCOPE { this.frame_chain.LastFrame().FastScopeChain().DeleteScope() } else if bytecode.OpCode() == abi.PUSH_CHAR { value := bytecode.Arg1() this.PushChar(value) } else if bytecode.OpCode() == abi.PUSH_SHORT { value := bytecode.Arg1() this.PushShort(value) } else if bytecode.OpCode() == abi.PUSH_INT { value := bytecode.Arg1() this.PushInt(value) } else if bytecode.OpCode() == abi.PUSH_LONG { value := bytecode.Arg1() this.PushLong(value) } else if bytecode.OpCode() == abi.PUSH_STRING { value := bytecode.Str1() this.PushString(value) } else if bytecode.OpCode() == abi.POP { this.Pop() } else if bytecode.OpCode() == abi.BEGIN_STRUCT { skeleton_name := bytecode.Str1() this.BeginStruct(skeleton_name) } else if bytecode.OpCode() == abi.APPEND_VOID { num_stars := bytecode.Arg1() field_name := bytecode.Str1() this.AppendVoid(num_stars, field_name) } else if bytecode.OpCode() == abi.APPEND_CHAR { num_stars := bytecode.Arg1() field_name := bytecode.Str1() this.AppendChar(num_stars, field_name) } else if bytecode.OpCode() == abi.APPEND_SHORT { num_stars := bytecode.Arg1() field_name := bytecode.Str1() this.AppendShort(num_stars, field_name) } else if bytecode.OpCode() == abi.APPEND_INT { num_stars := bytecode.Arg1() field_name := bytecode.Str1() this.AppendInt(num_stars, field_name) } else if bytecode.OpCode() == abi.APPEND_LONG { num_stars := bytecode.Arg1() field_name := bytecode.Str1() this.AppendLong(num_stars, field_name) } else if bytecode.OpCode() == abi.APPEND_STRUCT { num_stars := bytecode.Arg1() struct_name := bytecode.Str1() field_name := bytecode.Str2() this.AppendStruct(num_stars, struct_name, field_name) } else if bytecode.OpCode() == abi.END_STRUCT { this.EndStruct() } else if bytecode.OpCode() == abi.NEW_GLOBAL_VOID { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewGlobalVoid(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_GLOBAL_CHAR { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewGlobalChar(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_GLOBAL_SHORT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewGlobalShort(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_GLOBAL_INT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewGlobalInt(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_GLOBAL_LONG { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewGlobalLong(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_VOID { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewFastVoid(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_CHAR { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewFastChar(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_SHORT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewFastShort(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_INT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewFastInt(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_LONG { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewFastLong(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_FAST_STRUCT { num_stars := bytecode.Arg1() struct_name := bytecode.Str1() symbol_name := bytecode.Str2() this.NewFastStruct(num_stars, struct_name, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_VOID { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewArgVoid(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_CHAR { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewArgChar(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_SHORT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewArgShort(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_INT { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewArgInt(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_LONG { num_stars := bytecode.Arg1() symbol_name := bytecode.Str1() this.NewArgLong(num_stars, symbol_name) } else if bytecode.OpCode() == abi.NEW_ARG_STRUCT { num_stars := bytecode.Arg1() struct_name := bytecode.Str1() symbol_name := bytecode.Str2() this.NewArgStruct(num_stars, struct_name, symbol_name) } else if bytecode.OpCode() == abi.NEW_RETURN_VOID { num_stars := bytecode.Arg1() this.NewReturnVoid(num_stars) } else if bytecode.OpCode() == abi.NEW_RETURN_CHAR { num_stars := bytecode.Arg1() this.NewReturnChar(num_stars) } else if bytecode.OpCode() == abi.NEW_RETURN_SHORT { num_stars := bytecode.Arg1() this.NewReturnShort(num_stars) } else if bytecode.OpCode() == abi.NEW_RETURN_INT { num_stars := bytecode.Arg1() this.NewReturnInt(num_stars) } else if bytecode.OpCode() == abi.NEW_RETURN_LONG { num_stars := bytecode.Arg1() this.NewReturnLong(num_stars) } else if bytecode.OpCode() == abi.NEW_RETURN_STRUCT { num_stars := bytecode.Arg1() struct_name := bytecode.Str1() this.NewReturnStruct(num_stars, struct_name) } else if bytecode.OpCode() == abi.SIZEOF_VOID { num_stars := bytecode.Arg1() this.SizeofVoid(num_stars) } else if bytecode.OpCode() == abi.SIZEOF_CHAR { num_stars := bytecode.Arg1() this.SizeofChar(num_stars) } else if bytecode.OpCode() == abi.SIZEOF_SHORT { num_stars := bytecode.Arg1() this.SizeofShort(num_stars) } else if bytecode.OpCode() == abi.SIZEOF_INT { num_stars := bytecode.Arg1() this.SizeofInt(num_stars) } else if bytecode.OpCode() == abi.SIZEOF_LONG { num_stars := bytecode.Arg1() this.SizeofLong(num_stars) } else if bytecode.OpCode() == abi.SIZEOF_STRUCT { num_stars := bytecode.Arg1() struct_name := bytecode.Str1() this.SizeofStruct(num_stars, struct_name) } else if bytecode.OpCode() == abi.GET_IDENTIFIER { symbol_name := bytecode.Str1() this.GetIdentifier(symbol_name) } else if bytecode.OpCode() == abi.GET_ARG_IDENTIFIER { symbol_name := bytecode.Str1() this.GetArgIdentifier(symbol_name) } else if bytecode.OpCode() == abi.GET_SUBSCRIPT { this.GetSubscript() } else if bytecode.OpCode() == abi.GET_ACCESS { field_name := bytecode.Str1() this.GetAccess(field_name) } else if bytecode.OpCode() == abi.GET_REFERENCE { field_name := bytecode.Str1() this.GetReference(field_name) } else if bytecode.OpCode() == abi.GET_ADDRESS { this.GetAddress() } else if bytecode.OpCode() == abi.GET_VALUE { this.GetValue() } else if bytecode.OpCode() == abi.ALLOC { this.Alloc() } else if bytecode.OpCode() == abi.FREE { this.Free() } else if bytecode.OpCode() == abi.ASSERT { this.Assert() } else if bytecode.OpCode() == abi.ADD { this.Add() } else if bytecode.OpCode() == abi.SUB { this.Sub() } else if bytecode.OpCode() == abi.MUL { this.Mul() } else if bytecode.OpCode() == abi.DIV { this.Div() } else if bytecode.OpCode() == abi.MOD { this.Mod() } else if bytecode.OpCode() == abi.LSHIFT { this.Lshift() } else if bytecode.OpCode() == abi.RSHIFT { this.Rshift() } else if bytecode.OpCode() == abi.NEGATE { this.Negate() } else if bytecode.OpCode() == abi.TILDE { this.Tilde() } else if bytecode.OpCode() == abi.SQRT { this.Sqrt() } else if bytecode.OpCode() == abi.BITWISE_AND { this.BitwiseAnd() } else if bytecode.OpCode() == abi.BITWISE_XOR { this.BitwiseXor() } else if bytecode.OpCode() == abi.BITWISE_OR { this.BitwiseOr() } else if bytecode.OpCode() == abi.LOGICAL_AND { this.LogicalAnd() } else if bytecode.OpCode() == abi.LOGICAL_OR { this.LogicalOr() } else if bytecode.OpCode() == abi.LOGICAL_NOT { this.LogicalNot() } else if bytecode.OpCode() == abi.EQ { this.Eq() } else if bytecode.OpCode() == abi.NOT_EQ { this.NotEq() } else if bytecode.OpCode() == abi.LESS { this.Less() } else if bytecode.OpCode() == abi.LESS_EQ { this.LessEq() } else if bytecode.OpCode() == abi.GREATER { this.Greater() } else if bytecode.OpCode() == abi.GREATER_EQ { this.GreaterEq() } else if bytecode.OpCode() == abi.CONDITIONAL { this.Conditional() } else if bytecode.OpCode() == abi.ASSIGN { this.Assign() } else if bytecode.OpCode() == abi.ASSIGN_STAR { this.AssignStar() } else if bytecode.OpCode() == abi.ASSIGN_DIV { this.AssignDiv() } else if bytecode.OpCode() == abi.ASSIGN_MOD { this.AssignMod() } else if bytecode.OpCode() == abi.ASSIGN_ADD { this.AssignAdd() } else if bytecode.OpCode() == abi.ASSIGN_SUB { this.AssignSub() } else if bytecode.OpCode() == abi.ASSIGN_LSHIFT { this.AssignLshift() } else if bytecode.OpCode() == abi.ASSIGN_RSHIFT { this.AssignRshift() } else if bytecode.OpCode() == abi.ASSIGN_BITWISE_AND { this.AssignBitwiseAnd() } else if bytecode.OpCode() == abi.ASSIGN_BITWISE_XOR { this.AssignBitwiseXor() } else if bytecode.OpCode() == abi.ASSIGN_BITWISE_OR { this.AssignBitwiseOr() } else if bytecode.OpCode() == abi.ASSIGN_PLUS_PLUS { this.AssignPlusPlus() } else if bytecode.OpCode() == abi.ASSIGN_MINUS_MINUS { this.AssignMinusMinus() } else if bytecode.OpCode() == abi.ASSIGN_RETURN { this.AssignReturn() } else if bytecode.OpCode() == abi.JUMP { label_name := bytecode.Str1() label := this.app.Label(label_name) this.Jump(label) } else if bytecode.OpCode() == abi.JUMP_IF_ZERO { label_name := bytecode.Str1() label := this.app.Label(label_name) this.JumpIfZero(label) } else if bytecode.OpCode() == abi.JUMP_IF_NONZERO { label_name := bytecode.Str1() label := this.app.Label(label_name) this.JumpIfNonZero(label) } else if bytecode.OpCode() == abi.CALL { label_name := bytecode.Str1() label := this.app.Label(label_name) this.Call(label) } else if bytecode.OpCode() == abi.RETURN { this.Return() } else if bytecode.OpCode() == abi.NOP { this.Nop() } else if bytecode.OpCode() == abi.DPU_ALLOC { dpu_id := bytecode.Arg1() this.DpuAlloc(dpu_id) } else if bytecode.OpCode() == abi.DPU_LOAD { this.DpuLoad() } else if bytecode.OpCode() == abi.DPU_PREPARE { this.DpuPrepare() } else if bytecode.OpCode() == abi.DPU_TRANSFER { this.DpuTransfer() } else if bytecode.OpCode() == abi.DPU_COPY_TO { this.DpuCopyTo() } else if bytecode.OpCode() == abi.DPU_COPY_FROM { this.DpuCopyFrom() } else if bytecode.OpCode() == abi.DPU_LAUNCH { this.DpuLaunch() } else if bytecode.OpCode() == abi.DPU_FREE { this.DpuFree() } else { err := errors.New("op code is not valid") panic(err) } if this.verbose >= 2 { fmt.Printf("%s\n", this.Stringify()) } } func (this *VirtualMachine) PushChar(value int64) { object := this.arena.NewChar(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) PushShort(value int64) { object := this.arena.NewShort(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) PushInt(value int64) { object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) PushLong(value int64) { object := this.arena.NewLong(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) PushString(value string) { object := this.arena.NewString(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.STRING, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Pop() { this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) BeginStruct(skeleton_name string) { skeleton := new(type_system.Skeleton) skeleton.Init(skeleton_name) this.type_registry.AddSkeleton(skeleton) this.cur_skeleton_name = new(string) *this.cur_skeleton_name = skeleton_name } func (this *VirtualMachine) AppendVoid(num_stars int64, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) AppendChar(num_stars int64, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) AppendShort(num_stars int64, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) AppendInt(num_stars int64, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) AppendLong(num_stars int64, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) AppendStruct(num_stars int64, struct_name string, field_name string) { skeleton := this.type_registry.Skeleton(*this.cur_skeleton_name) type_variable := new(type_system.TypeVariable) type_variable.InitStruct(type_system.STRUCT, struct_name, int(num_stars)) field := new(type_system.Field) field.Init(type_variable, field_name) skeleton.Append(field) } func (this *VirtualMachine) EndStruct() { this.cur_skeleton_name = nil } func (this *VirtualMachine) NewGlobalVoid(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.GlobalScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewGlobalChar(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewChar(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.GlobalScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewGlobalShort(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewShort(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.GlobalScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewGlobalInt(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.GlobalScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewGlobalLong(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewLong(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.GlobalScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastVoid(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastChar(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewChar(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastShort(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewShort(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastInt(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastLong(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewLong(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewFastStruct(num_stars int64, struct_name string, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewStruct(struct_name, this.type_registry.SkeletonSize(struct_name)) } type_variable := new(type_system.TypeVariable) type_variable.InitStruct(type_system.STRUCT, struct_name, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().FastScopeChain().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgVoid(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgChar(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewChar(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgShort(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewShort(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgInt(num_stars int64, symbol_name string) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgLong(num_stars int64, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewLong(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewArgStruct(num_stars int64, struct_name string, symbol_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewStruct(struct_name, this.type_registry.SkeletonSize(struct_name)) } type_variable := new(type_system.TypeVariable) type_variable.InitStruct(type_system.STRUCT, struct_name, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) symbol_ := new(symbol.Symbol) symbol_.Init(symbol_name, type_variable, object) this.frame_chain.LastFrame().ArgScope().AddSymbol(symbol_) } func (this *VirtualMachine) NewReturnVoid(num_stars int64) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) NewReturnChar(num_stars int64) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewChar(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.CHAR, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) NewReturnShort(num_stars int64) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewShort(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.SHORT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) NewReturnInt(num_stars int64) { object := this.arena.NewInt(0) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) NewReturnLong(num_stars int64) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewLong(0) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.LONG, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) NewReturnStruct(num_stars int64, struct_name string) { var object *base.Object if num_stars > 0 { object = this.arena.NewInt(0) } else { object = this.arena.NewStruct(struct_name, this.type_registry.SkeletonSize(struct_name)) } type_variable := new(type_system.TypeVariable) type_variable.InitStruct(type_system.STRUCT, struct_name, int(num_stars)) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().ReturnStack().Push(stack_item) } func (this *VirtualMachine) SizeofVoid(num_stars int64) { var value int64 if num_stars == 0 { err := errors.New("num stars == 0") panic(err) } else { value = 4 } object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) SizeofChar(num_stars int64) { var value int64 if num_stars == 0 { value = 1 } else { value = 4 } object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) SizeofShort(num_stars int64) { var value int64 if num_stars == 0 { value = 2 } else { value = 4 } object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) SizeofInt(num_stars int64) { value := int64(4) object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) SizeofLong(num_stars int64) { var value int64 if num_stars == 0 { value = 8 } else { value = 4 } object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) SizeofStruct(num_stars int64, struct_name string) { var value int64 if num_stars == 0 { value = this.type_registry.SkeletonSize(struct_name) } else { value = 4 } object := this.arena.NewInt(value) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.INT, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetIdentifier(symbol_name string) { var symbol_ *symbol.Symbol if this.frame_chain.LastFrame().FastScopeChain().HasSymbol(symbol_name) { symbol_ = this.frame_chain.LastFrame().FastScopeChain().Symbol(symbol_name) } else if this.frame_chain.GlobalScope().HasSymbol(symbol_name) { symbol_ = this.frame_chain.GlobalScope().Symbol(symbol_name) } else { err_msg := fmt.Sprintf("symbol (%s) is not found", symbol_name) err := errors.New(err_msg) panic(err) } type_variable := symbol_.TypeVariable() object := symbol_.Object() stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetArgIdentifier(symbol_name string) { var symbol_ *symbol.Symbol if this.frame_chain.LastFrame().ArgScope().HasSymbol(symbol_name) { symbol_ = this.frame_chain.LastFrame().ArgScope().Symbol(symbol_name) } else { err_msg := fmt.Sprintf("symbol (%s) is not found", symbol_name) err := errors.New(err_msg) panic(err) } type_variable := symbol_.TypeVariable() object := symbol_.Object() stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetSubscript() { base_ := this.frame_chain.LastFrame().Stack().Front(1) index := this.frame_chain.LastFrame().Stack().Front(0) base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() index_value := this.arena.Pool().Memory().Read(index.Address(), index.Size()).SignedValue() var offset int64 var size int64 type_variable := new(type_system.TypeVariable) if base_.TypeVariable().NumStars() == 0 { err := errors.New("base is not a pointer") panic(err) } else if base_.TypeVariable().NumStars() == 1 { if base_.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("type variable type is void") panic(err) } else if base_.TypeVariable().TypeVariableType() == type_system.CHAR { offset = index_value size = 1 type_variable.InitPrimitive(type_system.CHAR, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.SHORT { offset = index_value * 2 size = 2 type_variable.InitPrimitive(type_system.SHORT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.INT { offset = index_value * 4 size = 4 type_variable.InitPrimitive(type_system.INT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.LONG { offset = index_value * 8 size = 8 type_variable.InitPrimitive(type_system.LONG, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.STRUCT { struct_name := base_.TypeVariable().StructName() offset = index_value * this.type_registry.SkeletonSize(struct_name) size = this.type_registry.SkeletonSize(struct_name) type_variable.InitStruct(type_system.STRUCT, struct_name, base_.TypeVariable().NumStars()-1) } else { err := errors.New("type variable type is not valid") panic(err) } } else { offset = index_value * 4 size = 4 if base_.TypeVariable().TypeVariableType() == type_system.VOID { type_variable.InitPrimitive(type_system.VOID, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.CHAR { type_variable.InitPrimitive(type_system.CHAR, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.SHORT { type_variable.InitPrimitive(type_system.SHORT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.INT { type_variable.InitPrimitive(type_system.INT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.LONG { type_variable.InitPrimitive(type_system.LONG, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.STRUCT { struct_name := base_.TypeVariable().StructName() type_variable.InitStruct(type_system.STRUCT, struct_name, base_.TypeVariable().NumStars()-1) } else { err := errors.New("type variable type is not valid") panic(err) } } stack_item := new(stack.StackItem) stack_item.Init(type_variable, base_value+offset, size) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetAccess(field_name string) { base_ := this.frame_chain.LastFrame().Stack().Front(0) if base_.TypeVariable().NumStars() != 0 { err := errors.New("base is a pointer") panic(err) } else if base_.TypeVariable().TypeVariableType() != type_system.STRUCT { err := errors.New("base is not a struct") panic(err) } struct_name := base_.TypeVariable().StructName() offset := this.type_registry.FieldOffset(struct_name, field_name) field := this.type_registry.Skeleton(struct_name).Field(field_name) type_variable := field.TypeVariable() var size int64 if field.TypeVariable().TypeVariableType() == type_system.VOID { if field.TypeVariable().NumStars() > 0 { size = 4 } else { err := errors.New("void type has no star") panic(err) } } else if field.TypeVariable().TypeVariableType() == type_system.CHAR { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 1 } } else if field.TypeVariable().TypeVariableType() == type_system.SHORT { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 2 } } else if field.TypeVariable().TypeVariableType() == type_system.INT { size = 4 } else if field.TypeVariable().TypeVariableType() == type_system.LONG { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 8 } } else if field.TypeVariable().TypeVariableType() == type_system.STRUCT { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = this.type_registry.SkeletonSize(base_.TypeVariable().StructName()) } } else { err := errors.New("type variable type is not valid") panic(err) } stack_item := new(stack.StackItem) stack_item.Init(type_variable, base_.Address()+offset, size) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetReference(field_name string) { base_ := this.frame_chain.LastFrame().Stack().Front(0) if base_.TypeVariable().NumStars() == 0 { err := errors.New("base is not a pointer") panic(err) } else if base_.TypeVariable().NumStars() > 1 { err := errors.New("base is a multi-dimensional pointer") panic(err) } else if base_.TypeVariable().TypeVariableType() != type_system.STRUCT { err := errors.New("base is not a struct") panic(err) } struct_name := base_.TypeVariable().StructName() offset := this.type_registry.FieldOffset(struct_name, field_name) field := this.type_registry.Skeleton(struct_name).Field(field_name) type_variable := field.TypeVariable() var size int64 if field.TypeVariable().TypeVariableType() == type_system.VOID { if field.TypeVariable().NumStars() > 0 { size = 4 } else { err := errors.New("void type has no star") panic(err) } } else if field.TypeVariable().TypeVariableType() == type_system.CHAR { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 1 } } else if field.TypeVariable().TypeVariableType() == type_system.SHORT { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 2 } } else if field.TypeVariable().TypeVariableType() == type_system.INT { size = 4 } else if field.TypeVariable().TypeVariableType() == type_system.LONG { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = 8 } } else if field.TypeVariable().TypeVariableType() == type_system.STRUCT { if field.TypeVariable().NumStars() > 0 { size = 4 } else { size = this.type_registry.SkeletonSize(base_.TypeVariable().StructName()) } } else { err := errors.New("type variable type is not valid") panic(err) } address := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() stack_item := new(stack.StackItem) stack_item.Init(type_variable, address+offset, size) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetAddress() { base_ := this.frame_chain.LastFrame().Stack().Front(0) object := this.arena.NewInt(base_.Address()) type_variable := new(type_system.TypeVariable) if base_.TypeVariable().TypeVariableType() == type_system.VOID { type_variable.InitPrimitive(type_system.VOID, base_.TypeVariable().NumStars()+1) } else if base_.TypeVariable().TypeVariableType() == type_system.CHAR { type_variable.InitPrimitive(type_system.CHAR, base_.TypeVariable().NumStars()+2) } else if base_.TypeVariable().TypeVariableType() == type_system.SHORT { type_variable.InitPrimitive(type_system.SHORT, base_.TypeVariable().NumStars()+1) } else if base_.TypeVariable().TypeVariableType() == type_system.INT { type_variable.InitPrimitive(type_system.INT, base_.TypeVariable().NumStars()+1) } else if base_.TypeVariable().TypeVariableType() == type_system.LONG { type_variable.InitPrimitive(type_system.LONG, base_.TypeVariable().NumStars()+1) } else if base_.TypeVariable().TypeVariableType() == type_system.STRUCT { type_variable.InitStruct(type_system.STRUCT, base_.TypeVariable().StructName(), base_.TypeVariable().NumStars()+1) } else { err := errors.New("type variable type is not valid") panic(err) } stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GetValue() { base_ := this.frame_chain.LastFrame().Stack().Front(0) base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() if base_.TypeVariable().NumStars() < 1 { err := errors.New("base is not a pointer") panic(err) } object := this.arena.Pool().Object(base_value) type_variable := new(type_system.TypeVariable) if base_.TypeVariable().TypeVariableType() == type_system.VOID { type_variable.InitPrimitive(type_system.VOID, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.CHAR { type_variable.InitPrimitive(type_system.CHAR, base_.TypeVariable().NumStars()-2) } else if base_.TypeVariable().TypeVariableType() == type_system.SHORT { type_variable.InitPrimitive(type_system.SHORT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.INT { type_variable.InitPrimitive(type_system.INT, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.LONG { type_variable.InitPrimitive(type_system.LONG, base_.TypeVariable().NumStars()-1) } else if base_.TypeVariable().TypeVariableType() == type_system.STRUCT { type_variable.InitStruct(type_system.STRUCT, base_.TypeVariable().StructName(), base_.TypeVariable().NumStars()-1) } else { err := errors.New("type variable type is not valid") panic(err) } stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Alloc() { base_ := this.frame_chain.LastFrame().Stack().Front(0) base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() object := this.arena.NewPointer(base_value) pointer := this.arena.NewInt(object.Address()) type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_system.VOID, 1) stack_item := new(stack.StackItem) stack_item.Init(type_variable, pointer.Address(), pointer.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Free() { base_ := this.frame_chain.LastFrame().Stack().Front(0) base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() this.arena.Free(base_value) this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) Assert() { base_ := this.frame_chain.LastFrame().Stack().Front(0) base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() if base_value == 0 { err := errors.New("assert") panic(err) } this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) Add() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value + roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be added") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Sub() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value - roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be subtracted") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Mul() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value * roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Div() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value / roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be divided") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Mod() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value % roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the modular operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Lshift() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value << roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be left shifted") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Rshift() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value >> roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be right shifted") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Negate() { operand := this.frame_chain.LastFrame().Stack().Front(0) if operand.TypeVariable().NumStars() != 0 { err := errors.New("operand's num stars != 0") panic(err) } operand_value := this.arena.Pool(). Memory(). Read(operand.Address(), operand.Size()). SignedValue() value := -operand_value var object *base.Object if operand.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if operand.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if operand.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if operand.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be negated") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(operand.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Tilde() { operand := this.frame_chain.LastFrame().Stack().Front(0) if operand.TypeVariable().NumStars() != 0 { err := errors.New("operand's num stars != 0") panic(err) } operand_value := this.arena.Pool(). Memory(). Read(operand.Address(), operand.Size()). SignedValue() value := ^operand_value var object *base.Object if operand.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if operand.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if operand.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if operand.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be tilded") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(operand.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Sqrt() { operand := this.frame_chain.LastFrame().Stack().Front(0) if operand.TypeVariable().NumStars() != 0 { err := errors.New("operand's num stars != 0") panic(err) } operand_value := this.arena.Pool(). Memory(). Read(operand.Address(), operand.Size()). SignedValue() value := int64(math.Sqrt(float64(operand_value))) var object *base.Object if operand.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if operand.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if operand.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if operand.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be tilded") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(operand.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) BitwiseAnd() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value & roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the bitwise and operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) BitwiseXor() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value ^ roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the bitwise xor operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) BitwiseOr() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() value := loperand_value | roperand_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the bitwise or operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) LogicalAnd() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value != 0 && roperand_value != 0 { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the bitwise or operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) LogicalOr() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value != 0 || roperand_value != 0 { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the bitwise or operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) LogicalNot() { operand := this.frame_chain.LastFrame().Stack().Front(0) if operand.TypeVariable().NumStars() != 0 { err := errors.New("operand's num stars != 0") panic(err) } operand_value := this.arena.Pool(). Memory(). Read(operand.Address(), operand.Size()). SignedValue() var value int64 if operand_value != 0 { value = 0 } else { value = 1 } var object *base.Object if operand.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if operand.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if operand.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if operand.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot be tilded") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(operand.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Eq() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value == roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the eq operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) NotEq() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value != roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the not eq operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Less() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value < roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the less operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) LessEq() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value <= roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the less eq operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Greater() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value > roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the greater operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) GreaterEq() { loperand := this.frame_chain.LastFrame().Stack().Front(1) roperand := this.frame_chain.LastFrame().Stack().Front(0) if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } type_variable_type := this.TypeCast(loperand, roperand) loperand_value := this.arena.Pool(). Memory(). Read(loperand.Address(), loperand.Size()). SignedValue() roperand_value := this.arena.Pool(). Memory(). Read(roperand.Address(), roperand.Size()). SignedValue() var value int64 if loperand_value >= roperand_value { value = 1 } else { value = 0 } var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("loperand and roperand cannot conduct the greater eq operation") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Push(stack_item) } func (this *VirtualMachine) Conditional() { condition_stack_item := this.frame_chain.LastFrame().Stack().Front(2) true_stack_item := this.frame_chain.LastFrame().Stack().Front(1) false_stack_item := this.frame_chain.LastFrame().Stack().Front(0) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() condition_value := this.arena.Pool(). Memory(). Read(condition_stack_item.Address(), condition_stack_item.Size()). SignedValue() if condition_value != 0 { this.frame_chain.LastFrame().Stack().Push(true_stack_item) } else { this.frame_chain.LastFrame().Stack().Push(false_stack_item) } } func (this *VirtualMachine) Assign() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) rvalue_byte_stream := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()) if lvalue.Size() > rvalue_byte_stream.Size() { for lvalue.Size() != rvalue_byte_stream.Size() { if rvalue_byte_stream.Signbit() { rvalue_byte_stream.Append(255) } else { rvalue_byte_stream.Append(0) } } } else if lvalue.Size() < rvalue_byte_stream.Size() { for lvalue.Size() != rvalue_byte_stream.Size() { rvalue_byte_stream.Remove(int(rvalue_byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), rvalue_byte_stream) if this.arena.Pool().HasObject(lvalue.Address()) { lvalue_object := this.arena.Pool().Object(lvalue.Address()) if !lvalue_object.HasTypeVariable() { lvalue_object.SetTypeVariable(rvalue.TypeVariable()) } } this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignStar() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value * rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignDiv() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value / rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignMod() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value % rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignAdd() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value + rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignSub() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value - rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignLshift() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value << rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignRshift() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value >> rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignBitwiseAnd() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value & rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignBitwiseXor() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value ^ rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignBitwiseOr() { lvalue := this.frame_chain.LastFrame().Stack().Front(1) rvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } else if rvalue.TypeVariable().NumStars() != 0 { err := errors.New("rvalue's num stars != 0") panic(err) } type_variable_type := this.TypeCast(lvalue, rvalue) lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() rvalue_value := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()).SignedValue() value := lvalue_value | rvalue_value var object *base.Object if type_variable_type == type_system.CHAR { object = this.arena.NewChar(value) } else if type_variable_type == type_system.SHORT { object = this.arena.NewShort(value) } else if type_variable_type == type_system.INT { object = this.arena.NewInt(value) } else if type_variable_type == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(type_variable_type, 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignPlusPlus() { lvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() value := lvalue_value + 1 var object *base.Object if lvalue.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(lvalue.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignMinusMinus() { lvalue := this.frame_chain.LastFrame().Stack().Front(0) if lvalue.TypeVariable().NumStars() != 0 { err := errors.New("lvalue's num stars != 0") panic(err) } lvalue_value := this.arena.Pool().Memory().Read(lvalue.Address(), lvalue.Size()).SignedValue() value := lvalue_value - 1 var object *base.Object if lvalue.TypeVariable().TypeVariableType() == type_system.CHAR { object = this.arena.NewChar(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.SHORT { object = this.arena.NewShort(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.INT { object = this.arena.NewInt(value) } else if lvalue.TypeVariable().TypeVariableType() == type_system.LONG { object = this.arena.NewLong(value) } else { err := errors.New("lvalue and rvalue cannot be multiplied") panic(err) } type_variable := new(type_system.TypeVariable) type_variable.InitPrimitive(lvalue.TypeVariable().TypeVariableType(), 0) stack_item := new(stack.StackItem) stack_item.Init(type_variable, object.Address(), object.Size()) byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) if lvalue.Size() > byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { if byte_stream.Signbit() { byte_stream.Append(255) } else { byte_stream.Append(0) } } } else if lvalue.Size() < byte_stream.Size() { for lvalue.Size() != byte_stream.Size() { byte_stream.Remove(int(byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), byte_stream) this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) AssignReturn() { lvalue := this.frame_chain.LastFrame().ReturnStack().Front(0) rvalue := this.frame_chain.LastFrame().Stack().Front(0) rvalue_byte_stream := this.arena.Pool().Memory().Read(rvalue.Address(), rvalue.Size()) if lvalue.Size() > rvalue_byte_stream.Size() { for lvalue.Size() != rvalue_byte_stream.Size() { if rvalue_byte_stream.Signbit() { rvalue_byte_stream.Append(255) } else { rvalue_byte_stream.Append(0) } } } else if lvalue.Size() < rvalue_byte_stream.Size() { for lvalue.Size() != rvalue_byte_stream.Size() { rvalue_byte_stream.Remove(int(rvalue_byte_stream.Size() - 1)) } } this.arena.Pool().Memory().Write(lvalue.Address(), lvalue.Size(), rvalue_byte_stream) this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) Jump(label *abi.Label) { this.frame_chain.LastFrame().Pc().Jump(label) } func (this *VirtualMachine) JumpIfZero(label *abi.Label) { value := this.frame_chain.LastFrame().Stack().Front(0) value_value := this.arena.Pool().Memory().Read(value.Address(), value.Size()).SignedValue() if value_value == 0 { this.frame_chain.LastFrame().Pc().Jump(label) } this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) JumpIfNonZero(label *abi.Label) { value := this.frame_chain.LastFrame().Stack().Front(0) value_value := this.arena.Pool().Memory().Read(value.Address(), value.Size()).SignedValue() if value_value != 0 { this.frame_chain.LastFrame().Pc().Jump(label) } this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) Call(label *abi.Label) { this.frame_chain.NewFrame(label) } func (this *VirtualMachine) Return() { this.frame_chain.DeleteFrame() } func (this *VirtualMachine) Nop() { } func (this *VirtualMachine) DpuAlloc(dpu_id int64) { if int(dpu_id) > this.num_dpus { err := errors.New("DpuAlloc allocates more number of DPUs than available") panic(err) } } func (this *VirtualMachine) DpuLoad() { thread_pool := new(core.ThreadPool) thread_pool.Init() for _, dpu_ := range this.Dpus() { dpu_load_job := new(DpuLoadJob) dpu_load_job.Init(this.task, dpu_) thread_pool.Enque(dpu_load_job) } thread_pool.Start() } func (this *VirtualMachine) DpuPrepare() { dpu_id := this.frame_chain.LastFrame().Stack().Front(1) pointer := this.frame_chain.LastFrame().Stack().Front(0) dpu_id_value := this.arena.Pool().Memory().Read(dpu_id.Address(), dpu_id.Size()).SignedValue() pointer_value := this.arena.Pool(). Memory(). Read(pointer.Address(), pointer.Size()). SignedValue() dpu_ := this.Dpus()[dpu_id_value] this.prepare_xfer_buf[dpu_] = pointer_value this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) DpuTransfer() { direction := this.frame_chain.LastFrame().Stack().Front(4) base_ := this.frame_chain.LastFrame().Stack().Front(3) offset := this.frame_chain.LastFrame().Stack().Front(2) size := this.frame_chain.LastFrame().Stack().Front(1) direction_value := this.arena.Pool(). Memory(). Read(direction.Address(), direction.Size()). SignedValue() offset_value := this.arena.Pool().Memory().Read(offset.Address(), offset.Size()).SignedValue() size_value := this.arena.Pool().Memory().Read(size.Address(), size.Size()).SignedValue() for _, dpu_ := range this.Dpus() { if pointer_value, pointer_found := this.prepare_xfer_buf[dpu_]; pointer_found { delete(this.prepare_xfer_buf, dpu_) if direction_value == 0 { if base_.TypeVariable().TypeVariableType() == type_system.STRING { base_string := this.DecodeString( this.arena.Pool().Memory().Read(base_.Address(), base_.Size()), ) base_string = base_string[1 : len(base_string)-1] wram_address, wram_address_found := this.task.Addresses()[base_string] if !wram_address_found { err_msg := fmt.Sprintf("WRAM address (%s) is not found", base_string) err := errors.New(err_msg) panic(err) } byte_stream := this.PrepareByteStream(pointer_value, size_value) dpu_.Dma(). TransferToWram(wram_address+offset_value, byte_stream.Size(), byte_stream) } else { base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() byte_stream := this.PrepareByteStream(pointer_value, size_value) dpu_.Dma().TransferToMram(base_value+offset_value, size_value, byte_stream) } } else if direction_value == 1 { if base_.TypeVariable().TypeVariableType() == type_system.STRING { base_string := this.DecodeString(this.arena.Pool().Memory().Read(base_.Address(), base_.Size())) base_string = base_string[1 : len(base_string)-1] wram_address, wram_address_found := this.task.Addresses()[base_string] if !wram_address_found { err_msg := fmt.Sprintf("WRAM address (%s) is not found", base_string) err := errors.New(err_msg) panic(err) } byte_stream := dpu_.Dma().TransferFromWram(wram_address+offset_value, size_value) this.arena.Pool().Memory().Write(pointer_value, size_value, byte_stream) } else { base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() byte_stream := dpu_.Dma().TransferFromMram(base_value+offset_value, size_value) this.arena.Pool().Memory().Write(pointer_value, size_value, byte_stream) } } else { err := errors.New("direction value is not 0 nor 1") panic(err) } } } this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) DpuCopyTo() { dpu_ := this.frame_chain.LastFrame().Stack().Front(4) base_ := this.frame_chain.LastFrame().Stack().Front(3) offset := this.frame_chain.LastFrame().Stack().Front(2) pointer := this.frame_chain.LastFrame().Stack().Front(1) size := this.frame_chain.LastFrame().Stack().Front(0) dpu_value := this.arena.Pool().Memory().Read(dpu_.Address(), dpu_.Size()).SignedValue() offset_value := this.arena.Pool().Memory().Read(offset.Address(), offset.Size()).SignedValue() pointer_value := this.arena.Pool(). Memory(). Read(pointer.Address(), pointer.Size()). SignedValue() size_value := this.arena.Pool().Memory().Read(size.Address(), size.Size()).SignedValue() if base_.TypeVariable().TypeVariableType() == type_system.STRING { base_string := this.DecodeString( this.arena.Pool().Memory().Read(base_.Address(), base_.Size()), ) base_string = base_string[1 : len(base_string)-1] wram_address, wram_address_found := this.task.Addresses()[base_string] if !wram_address_found { err_msg := fmt.Sprintf("WRAM address (%s) is not found", base_string) err := errors.New(err_msg) panic(err) } byte_stream := this.PrepareByteStream(pointer_value, size_value) this.Dpus()[dpu_value].Dma(). TransferToWram(wram_address+offset_value, byte_stream.Size(), byte_stream) } else { base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() channel_id := int(dpu_value) / (this.num_ranks_per_channel * this.num_dpus_per_rank) rank_id := (int(dpu_value) % (this.num_ranks_per_channel * this.num_dpus_per_rank)) / this.num_dpus_per_rank dpu_id := int(dpu_value) % this.num_dpus_per_rank simulated_dpu := this.channels[channel_id].Ranks()[rank_id].Dpus()[dpu_id] byte_stream := this.PrepareByteStream(pointer_value, size_value) simulated_dpu.Dma().TransferToMram(base_value+offset_value, size_value, byte_stream) } this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) DpuCopyFrom() { dpu_ := this.frame_chain.LastFrame().Stack().Front(4) base_ := this.frame_chain.LastFrame().Stack().Front(3) offset := this.frame_chain.LastFrame().Stack().Front(2) pointer := this.frame_chain.LastFrame().Stack().Front(1) size := this.frame_chain.LastFrame().Stack().Front(0) dpu_value := this.arena.Pool().Memory().Read(dpu_.Address(), dpu_.Size()).SignedValue() offset_value := this.arena.Pool().Memory().Read(offset.Address(), offset.Size()).SignedValue() pointer_value := this.arena.Pool(). Memory(). Read(pointer.Address(), pointer.Size()). SignedValue() size_value := this.arena.Pool().Memory().Read(size.Address(), size.Size()).SignedValue() if base_.TypeVariable().TypeVariableType() == type_system.STRING { base_string := this.DecodeString( this.arena.Pool().Memory().Read(base_.Address(), base_.Size()), ) base_string = base_string[1 : len(base_string)-1] wram_address, wram_address_found := this.task.Addresses()[base_string] if !wram_address_found { err_msg := fmt.Sprintf("WRAM address (%s) is not found", base_string) err := errors.New(err_msg) panic(err) } byte_stream := this.Dpus()[dpu_value].Dma(). TransferFromWram(wram_address+offset_value, size_value) this.arena.Pool().Memory().Write(pointer_value, size_value, byte_stream) } else { base_value := this.arena.Pool().Memory().Read(base_.Address(), base_.Size()).SignedValue() channel_id := int(dpu_value) / (this.num_ranks_per_channel * this.num_dpus_per_rank) rank_id := (int(dpu_value) % (this.num_ranks_per_channel * this.num_dpus_per_rank)) / this.num_dpus_per_rank dpu_id := int(dpu_value) % this.num_dpus_per_rank simulated_dpu := this.channels[channel_id].Ranks()[rank_id].Dpus()[dpu_id] byte_stream := simulated_dpu.Dma().TransferFromMram(base_value+offset_value, size_value) this.arena.Pool().Memory().Write(pointer_value, size_value, byte_stream) } this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) DpuLaunch() { config_loader := new(misc.ConfigLoader) config_loader.Init() for _, dpu_ := range this.Dpus() { threads := dpu_.Threads() for _, thread := range threads { bootstrap := config_loader.IramOffset() thread.RegFile().WritePcReg(bootstrap) } dpu_.Boot() } thread_pool := new(core.ThreadPool) thread_pool.Init() for _, dpu_ := range this.Dpus() { dpu_cycle_job := new(DpuComputeCycleJob) dpu_cycle_job.Init(this.task.SysEnd(), dpu_) thread_pool.Enque(dpu_cycle_job) } thread_pool.Start() for _, dpu_ := range this.Dpus() { dpu_.Unboot() } this.frame_chain.LastFrame().Stack().Pop() this.frame_chain.LastFrame().Stack().Pop() } func (this *VirtualMachine) DpuFree() { } func (this *VirtualMachine) Banks() []*bank.Bank { return this.memory_controller.Banks() } func (this *VirtualMachine) Dpus() []*dpu.Dpu { dpus := make([]*dpu.Dpu, 0) for _, channel_ := range this.channels { dpus = append(dpus, channel_.Dpus()...) } return dpus } func (this *VirtualMachine) TypeCast( loperand *stack.StackItem, roperand *stack.StackItem, ) type_system.TypeVariableType { if loperand.TypeVariable().NumStars() != 0 { err := errors.New("loperand's num stars != 0") panic(err) } else if roperand.TypeVariable().NumStars() != 0 { err := errors.New("roperand's num stars != 0") panic(err) } if loperand.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("loperand's type variable type == void") panic(err) } else if loperand.TypeVariable().TypeVariableType() == type_system.CHAR { if roperand.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("roperand's type variable type == void") panic(err) } else if roperand.TypeVariable().TypeVariableType() == type_system.CHAR { return type_system.CHAR } else if roperand.TypeVariable().TypeVariableType() == type_system.SHORT { return type_system.SHORT } else if roperand.TypeVariable().TypeVariableType() == type_system.INT { return type_system.INT } else if roperand.TypeVariable().TypeVariableType() == type_system.LONG { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.STRUCT { err := errors.New("roperand's type variable type == struct") panic(err) } else { err := errors.New("roperand's type variable type is not valid") panic(err) } } else if loperand.TypeVariable().TypeVariableType() == type_system.SHORT { if roperand.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("roperand's type variable type == void") panic(err) } else if roperand.TypeVariable().TypeVariableType() == type_system.CHAR { return type_system.SHORT } else if roperand.TypeVariable().TypeVariableType() == type_system.SHORT { return type_system.SHORT } else if roperand.TypeVariable().TypeVariableType() == type_system.INT { return type_system.INT } else if roperand.TypeVariable().TypeVariableType() == type_system.LONG { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.STRUCT { err := errors.New("roperand's type variable type == struct") panic(err) } else { err := errors.New("roperand's type variable type is not valid") panic(err) } } else if loperand.TypeVariable().TypeVariableType() == type_system.INT { if roperand.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("roperand's type variable type == void") panic(err) } else if roperand.TypeVariable().TypeVariableType() == type_system.CHAR { return type_system.INT } else if roperand.TypeVariable().TypeVariableType() == type_system.SHORT { return type_system.INT } else if roperand.TypeVariable().TypeVariableType() == type_system.INT { return type_system.INT } else if roperand.TypeVariable().TypeVariableType() == type_system.LONG { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.STRUCT { err := errors.New("roperand's type variable type == struct") panic(err) } else { err := errors.New("roperand's type variable type is not valid") panic(err) } } else if loperand.TypeVariable().TypeVariableType() == type_system.LONG { if roperand.TypeVariable().TypeVariableType() == type_system.VOID { err := errors.New("roperand's type variable type == void") panic(err) } else if roperand.TypeVariable().TypeVariableType() == type_system.CHAR { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.SHORT { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.INT { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.LONG { return type_system.LONG } else if roperand.TypeVariable().TypeVariableType() == type_system.STRUCT { err := errors.New("roperand's type variable type == struct") panic(err) } else { err := errors.New("roperand's type variable type is not valid") panic(err) } } else if loperand.TypeVariable().TypeVariableType() == type_system.STRUCT { err := errors.New("loperand's type variable type == struct") panic(err) } else { err := errors.New("loperand's type variable type is not valid") panic(err) } } func (this *VirtualMachine) DecodeString(byte_stream *encoding.ByteStream) string { ascii_encoder := new(encoding.AsciiEncoder) ascii_encoder.Init() return ascii_encoder.Decode(byte_stream) } func (this *VirtualMachine) Checkpoint() { this.memory_controller.Flush() for _, object := range this.arena.Pool().Objects() { vm_address := object.Address() size := object.Size() byte_stream := this.arena.Pool().Memory().Read(object.Address(), object.Size()) this.memory_controller.VmWrite(vm_address, size, byte_stream) } } func (this *VirtualMachine) PrepareByteStream( pointer int64, size int64, ) *encoding.ByteStream { object := this.arena.Pool().Memory().Read(pointer, size) byte_stream := new(encoding.ByteStream) byte_stream.Init() for i := int64(0); i < size; i++ { byte_stream.Append(object.Get(int(i))) } return byte_stream } func (this *VirtualMachine) SimulateMemory() { for len(this.push_xfer) > 0 { thread_pool := new(core.ThreadPool) thread_pool.Init() for _, bank_ := range this.Banks() { bank_cycle_job := new(BankCycleJob) bank_cycle_job.Init(bank_) thread_pool.Enque(bank_cycle_job) } for _, dpu_ := range this.Dpus() { dpu_cycle_job := new(DpuCycleJob) dpu_cycle_job.Init(dpu_) thread_pool.Enque(dpu_cycle_job) } thread_pool.Start() for _, vm_channel_ := range this.memory_controller.VmChannels() { vm_channel_.Cycle() } for _, channel_ := range this.channels { channel_.Cycle() } this.memory_controller.Cycle() if this.memory_controller.CanPop() { transfer_command := this.memory_controller.Pop() if !transfer_command.IsVmReady() { err := errors.New("transfer command is not VM ready") panic(err) } else if !transfer_command.IsReady() { err := errors.New("transfer command is not ready") panic(err) } delete(this.push_xfer, transfer_command) if transfer_command.TransferCommandType() == bank.DEVICE_TO_HOST { this.arena.Pool().Memory().Write( transfer_command.VmAddress(), transfer_command.Size(), transfer_command.ByteStream(), ) } } } } func (this *VirtualMachine) Dump() { file_dumper := new(misc.FileDumper) file_dumper.Init(filepath.Join(this.bin_dirpath, "log.txt")) lines := make([]string, 0) for _, dpu_ := range this.Dpus() { lines = append(lines, dpu_.StatFactory().ToLines()...) lines = append(lines, dpu_.ThreadScheduler().StatFactory().ToLines()...) lines = append(lines, dpu_.Logic().StatFactory().ToLines()...) lines = append(lines, dpu_.Logic().CycleRule().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().MemoryScheduler().StatFactory().ToLines()...) lines = append(lines, dpu_.MemoryController().RowBuffer().StatFactory().ToLines()...) } lines = append(lines, this.memory_controller.MemoryScheduler().StatFactory().ToLines()...) for _, vm_channel := range this.memory_controller.VmChannels() { for _, rank_ := range vm_channel.Ranks() { for _, bank_ := range rank_.Banks() { lines = append(lines, bank_.StatFactory().ToLines()...) lines = append(lines, bank_.RowBuffer().StatFactory().ToLines()...) } } } file_dumper.WriteLines(lines) } func (this *VirtualMachine) Stringify() string { ss := "\n=============== STACK ===============\n" for i := 0; i < this.frame_chain.LastFrame().Stack().Length(); i++ { stack_item := this.frame_chain.LastFrame().Stack().Front(i) byte_stream := this.arena.Pool().Memory().Read(stack_item.Address(), stack_item.Size()) if byte_stream.Size() <= 8 { ss += fmt.Sprintf("%d: %d\n", i, byte_stream.SignedValue()) } else { ss += fmt.Sprintf("%d: XXX\n", i) } } ss += "=====================================\n" return ss } ================================================ FILE: golang_vm/uPIMulator/src/main.go ================================================ package main import ( "fmt" "os" "path/filepath" "uPIMulator/src/device/compiler" "uPIMulator/src/device/linker" "uPIMulator/src/host/interpreter" "uPIMulator/src/misc" "uPIMulator/src/program" "uPIMulator/src/system" ) func main() { command_line_parser := InitCommandLineParser() command_line_parser.Parse(os.Args) if command_line_parser.IsArgSet("help") { fmt.Printf("%s", command_line_parser.StringifyHelpMsgs()) } else { command_line_validator := new(misc.CommandLineValidator) command_line_validator.Init(command_line_parser) command_line_validator.Validate() config_loader := new(misc.ConfigLoader) config_loader.Init() config_validator := new(misc.ConfigValidator) config_validator.Init(config_loader) config_validator.Validate() bin_dirpath := command_line_parser.StringParameter("bin_dirpath") if _, err := os.Stat(bin_dirpath); !os.IsNotExist(err) { remove_err := os.RemoveAll(bin_dirpath) if remove_err != nil { panic(remove_err) } mkdir_err := os.MkdirAll(bin_dirpath, os.ModePerm) if mkdir_err != nil { panic(mkdir_err) } } args_filepath := filepath.Join(bin_dirpath, "args.txt") options_filepath := filepath.Join(bin_dirpath, "options.txt") args_file_dumper := new(misc.FileDumper) args_file_dumper.Init(args_filepath) args_file_dumper.WriteLines([]string{command_line_parser.StringifyArgs()}) options_file_dumper := new(misc.FileDumper) options_file_dumper.Init(options_filepath) options_file_dumper.WriteLines([]string{command_line_parser.StringifyOptions()}) compiler_ := new(compiler.Compiler) compiler_.Init(command_line_parser) compiler_.Compile() linker_ := new(linker.Linker) linker_.Init(command_line_parser) linker_.Link() task := new(program.Task) task.Init(command_line_parser) interpreter_ := new(interpreter.Interpreter) interpreter_.Init(command_line_parser, task.SysUsedMramEnd()) interpreter_.Interpret() app := new(program.App) app.Init(command_line_parser) system_ := new(system.System) system_.Init(command_line_parser) system_.Simulate(app, task) system_.Dump() system_.Fini() } } func InitCommandLineParser() *misc.CommandLineParser { command_line_parser := new(misc.CommandLineParser) command_line_parser.Init() // NOTE(dongjae.lee@kaist.ac.kr): Explanation of verbose levels // level 0: Only prints simulation output // level 1: level 0 + prints UPMEM instruction executed per each logic cycle // level 2: level 1 + prints host VM's stack and UPMEM register file values per each logic cycle command_line_parser.AddOption(misc.INT, "verbose", "1", "verbosity of the simulation") command_line_parser.AddOption(misc.STRING, "benchmark", "GEMV", "benchmark name") command_line_parser.AddOption(misc.INT, "num_channels", "1", "number of PIM memory channels") command_line_parser.AddOption( misc.INT, "num_ranks_per_channel", "1", "number of ranks per channel", ) command_line_parser.AddOption(misc.INT, "num_dpus_per_rank", "4", "number of DPUs per rank") command_line_parser.AddOption(misc.INT, "num_vm_channels", "1", "number of VM memory channels") command_line_parser.AddOption( misc.INT, "num_vm_ranks_per_channel", "2", "number of VM ranks per channel", ) command_line_parser.AddOption( misc.INT, "num_vm_banks_per_rank", "16", "number of VM banks per rank", ) command_line_parser.AddOption(misc.INT, "num_tasklets", "16", "number of tasklets") command_line_parser.AddOption(misc.STRING, "data_prep_params", "65536", "data preparation parameter") command_line_parser.AddOption( misc.STRING, "root_dirpath", "/home/via/uPIMulator/golang_vm/uPIMulator", "path to the root directory", ) command_line_parser.AddOption(misc.STRING, "bin_dirpath", "/home/via/uPIMulator/golang_vm/uPIMulator/bin", "path to the bin directory") command_line_parser.AddOption(misc.INT, "logic_frequency", "350", "DPU logic frequency in MHz") command_line_parser.AddOption(misc.INT, "memory_frequency", "2400", "DPU MRAM frequency in MHz") command_line_parser.AddOption(misc.INT, "num_pipeline_stages", "14", "number of DPU logic pipeline stages") command_line_parser.AddOption(misc.INT, "num_revolver_scheduling_cycles", "11", "number of DPU logic revolver scheduling cycles") command_line_parser.AddOption(misc.INT, "wordline_size", "1024", "row buffer size per single DPU's MRAM in bytes") command_line_parser.AddOption(misc.INT, "min_access_granularity", "8", "DPU MRAM's minimum access granularity in bytes") command_line_parser.AddOption(misc.INT, "reorder_window_size", "256", "FR-FCFS reorder window size") command_line_parser.AddOption( misc.INT, "t_rcd", "32", "DPU MRAM t_rcd timing parameter [cycle]", ) command_line_parser.AddOption( misc.INT, "t_ras", "78", "DPU MRAM t_ras timing parameter [cycle]", ) command_line_parser.AddOption(misc.INT, "t_rp", "32", "DPU MRAM t_rp timing parameter [cycle]") command_line_parser.AddOption(misc.INT, "t_cl", "32", "DPU MRAM t_cl timing parameter [cycle]") command_line_parser.AddOption(misc.INT, "t_bl", "8", "DPU MRAM t_bl timing parameter [cycle]") return command_line_parser } ================================================ FILE: golang_vm/uPIMulator/src/misc/command_line_option.go ================================================ package misc import ( "errors" "fmt" "strconv" ) type CommandLineOptionType int const ( BOOL = iota INT STRING ) type CommandLineOption struct { command_line_option_type CommandLineOptionType option string default_parameter string custom_parameter string help_msg string } func (this *CommandLineOption) Init( command_line_option_type CommandLineOptionType, option string, default_parameter string, help_msg string, ) { this.command_line_option_type = command_line_option_type this.option = option this.default_parameter = default_parameter this.custom_parameter = "" this.help_msg = help_msg } func (this *CommandLineOption) CommandLineOptionType() CommandLineOptionType { return this.command_line_option_type } func (this *CommandLineOption) Option() string { return this.option } func (this *CommandLineOption) Parameter() string { if this.custom_parameter == "" { return this.default_parameter } else { return this.custom_parameter } } func (this *CommandLineOption) HelpMsg() string { return this.help_msg } func (this *CommandLineOption) SetCustomParameter(custom_parameter string) { if this.custom_parameter != "" { err_msg := fmt.Sprintf("custom parameter (%s) is already set", custom_parameter) err := errors.New(err_msg) panic(err) } this.custom_parameter = custom_parameter } func (this *CommandLineOption) BoolParameter() bool { if this.Parameter() == "true" { return true } else if this.Parameter() == "false" { return false } else { err_msg := fmt.Sprintf("parameter (%s) is not true or false", this.Parameter()) err := errors.New(err_msg) panic(err) } } func (this *CommandLineOption) IntParameter() int64 { int_parameter, err := strconv.ParseInt(this.Parameter(), 10, 64) if err != nil { panic(err) } return int_parameter } func (this *CommandLineOption) StringParameter() string { return this.Parameter() } ================================================ FILE: golang_vm/uPIMulator/src/misc/command_line_parser.go ================================================ package misc import ( "errors" "fmt" "slices" "strconv" "strings" ) type CommandLineParser struct { command_line_options map[string]*CommandLineOption args map[string]bool } func (this *CommandLineParser) Init() { this.command_line_options = make(map[string]*CommandLineOption) this.args = make(map[string]bool) } func (this *CommandLineParser) AddOption( command_line_option_type CommandLineOptionType, option string, default_parameter string, help_msg string, ) { if _, found := this.command_line_options[option]; found { err_msg := fmt.Sprintf("option (%s) is already added to the parser") err := errors.New(err_msg) panic(err) } command_line_option := new(CommandLineOption) command_line_option.Init(command_line_option_type, option, default_parameter, help_msg) this.command_line_options[option] = command_line_option } func (this *CommandLineParser) Parse(os_args []string) { for i := 1; i < len(os_args); i++ { os_arg := os_args[i] if os_arg[0:2] == "--" { option := os_arg[2:] custom_parameter := os_args[i+1] this.command_line_options[option].SetCustomParameter(custom_parameter) i++ } else if os_arg[0:1] == "-" { arg := os_arg[1:] if _, found := this.args[arg]; found { err_msg := fmt.Sprintf("arg (%s) is already set", arg) err := errors.New(err_msg) panic(err) } this.args[arg] = true } else { err := errors.New("command line options are corrupted") panic(err) } } } func (this *CommandLineParser) BoolParameter(option string) bool { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.BoolParameter() } func (this *CommandLineParser) IntParameter(option string) int64 { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.IntParameter() } func (this *CommandLineParser) StringParameter(option string) string { if _, found := this.command_line_options[option]; !found { err_msg := fmt.Sprintf("option (%s) is not found", option) err := errors.New(err_msg) panic(err) } command_line_option := this.command_line_options[option] return command_line_option.StringParameter() } func (this *CommandLineParser) DataPrepParams() []int { string_params := strings.Split(this.StringParameter("data_prep_params"), ",") data_prep_params := make([]int, 0) for _, string_param := range string_params { int_param, err := strconv.Atoi(string_param) if err != nil { panic(err) } data_prep_params = append(data_prep_params, int_param) } return data_prep_params } func (this *CommandLineParser) IsArgSet(arg string) bool { if _, found := this.args[arg]; found { return true } else { return false } } func (this *CommandLineParser) Options() []string { options := make([]string, 0) for option := range this.command_line_options { options = append(options, option) } slices.Sort(options) return options } func (this *CommandLineParser) Args() []string { args := make([]string, 0) for arg := range this.args { args = append(args, arg) } slices.Sort(args) return args } func (this *CommandLineParser) StringifyOptions() string { str := "OPTIONS\n" for option, command_line_option := range this.command_line_options { str += option + " --> " + command_line_option.Parameter() + "\n" } return str } func (this *CommandLineParser) StringifyArgs() string { str := "ARGS\n" for arg := range this.args { str += arg + "\n" } return str } func (this *CommandLineParser) StringifyHelpMsgs() string { str := "HELP_MSGS\n" for option, command_line_option := range this.command_line_options { str += option + " --> " + command_line_option.HelpMsg() + "\n" } return str } ================================================ FILE: golang_vm/uPIMulator/src/misc/command_line_validator.go ================================================ package misc import ( "errors" "fmt" "os" ) type CommandLineValidator struct { command_line_parser *CommandLineParser } func (this *CommandLineValidator) Init(command_line_parser *CommandLineParser) { this.command_line_parser = command_line_parser } func (this *CommandLineValidator) Validate() { if this.command_line_parser.IntParameter("num_channels") <= 0 { err := errors.New("num_channels <= 0") panic(err) } if this.command_line_parser.IntParameter("num_ranks_per_channel") <= 0 { err := errors.New("num_ranks <= 0") panic(err) } if this.command_line_parser.IntParameter("num_dpus_per_rank") <= 0 { err := errors.New("num_dpus <= 0") panic(err) } if this.command_line_parser.IntParameter("num_vm_channels") <= 0 { err := errors.New("num_vm_channels <= 0") panic(err) } if this.command_line_parser.IntParameter("num_vm_ranks_per_channel") <= 0 { err := errors.New("num_vm_ranks_per_channel <= 0") panic(err) } if this.command_line_parser.IntParameter("num_vm_banks_per_rank") <= 0 { err := errors.New("num_vm_banks_per_rank <= 0") panic(err) } if this.command_line_parser.IntParameter("num_tasklets") <= 0 { err := errors.New("num_tasklets <= 0") panic(err) } if _, stat_err := os.Stat(this.command_line_parser.StringParameter("root_dirpath")); os.IsNotExist( stat_err, ) { err_msg := fmt.Sprintf( "root_dirpath (%s) does not exist", this.command_line_parser.StringParameter("root_dirpath"), ) err := errors.New(err_msg) panic(err) } if this.command_line_parser.IntParameter("logic_frequency") <= 0 { err := errors.New("logic_frequency <= 0") panic(err) } if this.command_line_parser.IntParameter("memory_frequency") <= 0 { err := errors.New("memory_frequency <= 0") panic(err) } if this.command_line_parser.IntParameter("num_pipeline_stages") <= 0 { err := errors.New("num_pipeline_stages <= 0") panic(err) } if this.command_line_parser.IntParameter("num_revolver_scheduling_cycles") < 0 { err := errors.New("num_revolver_scheduling_cycles < 0") panic(err) } if this.command_line_parser.IntParameter("wordline_size") <= 0 { err := errors.New("wordline_size <= 0") panic(err) } if this.command_line_parser.IntParameter("min_access_granularity") <= 0 { err := errors.New("min_access_granularity <= 0") panic(err) } if this.command_line_parser.IntParameter("t_rcd") < 0 { err := errors.New("t_rcd < 0") panic(err) } if this.command_line_parser.IntParameter("t_ras") < 0 { err := errors.New("t_ras < 0") panic(err) } if this.command_line_parser.IntParameter("t_rp") < 0 { err := errors.New("t_rp < 0") panic(err) } if this.command_line_parser.IntParameter("t_cl") < 0 { err := errors.New("t_cl < 0") panic(err) } if this.command_line_parser.IntParameter("t_bl") < 0 { err := errors.New("t_bl < 0") panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/misc/config_loader.go ================================================ package misc type ConfigLoader struct { } func (this *ConfigLoader) Init() { } func (this *ConfigLoader) AddressWidth() int { return 32 } func (this *ConfigLoader) AtomicDataWidth() int { return 32 } func (this *ConfigLoader) AtomicOffset() int64 { return 0 } func (this *ConfigLoader) AtomicSize() int64 { return 256 } func (this *ConfigLoader) IramDataWidth() int { return 96 } func (this *ConfigLoader) IramOffset() int64 { return 384 * 1024 } func (this *ConfigLoader) IramSize() int64 { return 48 * 1024 } func (this *ConfigLoader) WramDataWidth() int { return 32 } func (this *ConfigLoader) WramOffset() int64 { return 512 } func (this *ConfigLoader) WramSize() int64 { return 128 * 1024 } func (this *ConfigLoader) MramDataWidth() int { return 32 } func (this *ConfigLoader) MramOffset() int64 { return 512 * 1024 } func (this *ConfigLoader) MramSize() int64 { return 64 * 1024 * 1024 } func (this *ConfigLoader) StackSize() int64 { return 2 * 1024 } func (this *ConfigLoader) HeapSize() int64 { return 4 * 1024 } func (this *ConfigLoader) NumGpRegisters() int { return 24 } func (this *ConfigLoader) MaxNumTasklets() int { return 24 } func (this *ConfigLoader) VmBankOffset() int64 { return 512 } func (this *ConfigLoader) VmBankSize() int64 { return 128 * 1024 * 1024 } func (this *ConfigLoader) VmBg0() int { return 6 } func (this *ConfigLoader) VmBg1() int { return 17 } func (this *ConfigLoader) VmBank() int { return 18 } func (this *ConfigLoader) VmMemorySize() int64 { return 1024 } func (this *ConfigLoader) GarbageCollectionThreshold() int64 { return 100 } ================================================ FILE: golang_vm/uPIMulator/src/misc/config_validator.go ================================================ package misc import ( "errors" ) type ConfigValidator struct { config_loader *ConfigLoader } func (this *ConfigValidator) Init(config_loader *ConfigLoader) { this.config_loader = config_loader } func (this *ConfigValidator) Validate() { if this.config_loader.AddressWidth() <= 0 { err := errors.New("address width <= 0") panic(err) } if this.config_loader.AtomicDataWidth() <= 0 { err := errors.New("atomic data width <= 0") panic(err) } if this.config_loader.IramDataWidth() <= 0 { err := errors.New("IRAM data width <= 0") panic(err) } if this.config_loader.WramDataWidth() <= 0 { err := errors.New("WRAM data width <= 0") panic(err) } if this.config_loader.MramDataWidth() <= 0 { err := errors.New("MRAM data width <= 0") panic(err) } if this.config_loader.AtomicOffset() < 0 { err := errors.New("atomic offset < 0") panic(err) } if this.config_loader.IramOffset() < 0 { err := errors.New("IRAM offset < 0") panic(err) } if this.config_loader.WramOffset() < 0 { err := errors.New("WRAM offset < 0") panic(err) } if this.config_loader.MramOffset() < 0 { err := errors.New("MRAM offset < 0") panic(err) } if this.config_loader.AtomicSize() <= 0 { err := errors.New("atomic size <= 0") panic(err) } if this.config_loader.IramSize() <= 0 { err := errors.New("IRAM size <= 0") panic(err) } if this.config_loader.WramSize() <= 0 { err := errors.New("WRAM size <= 0") panic(err) } if this.config_loader.MramSize() <= 0 { err := errors.New("MRAM size <= 0") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.IramOffset(), this.config_loader.IramSize(), ) { err := errors.New("atomic and IRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.WramOffset(), this.config_loader.WramSize(), ) { err := errors.New("atomic and WRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.AtomicOffset(), this.config_loader.AtomicSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("atomic and MRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.IramOffset(), this.config_loader.IramSize(), this.config_loader.WramOffset(), this.config_loader.WramSize(), ) { err := errors.New("IRAM and WRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.IramOffset(), this.config_loader.IramSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("IRAM and MRAM are overlapped") panic(err) } if this.AreOverlapped( this.config_loader.WramOffset(), this.config_loader.WramSize(), this.config_loader.MramOffset(), this.config_loader.MramSize(), ) { err := errors.New("WRAM and MRAM are overlapped") panic(err) } if this.config_loader.StackSize() <= 0 { err := errors.New("stack size <= 0") panic(err) } if this.config_loader.HeapSize() <= 0 { err := errors.New("heap size <= 0") panic(err) } if this.config_loader.NumGpRegisters() <= 0 { err := errors.New("num gp registers <= 0") panic(err) } if this.config_loader.MaxNumTasklets() <= 0 { err := errors.New("max num tasklets <= 0") panic(err) } } func (this *ConfigValidator) AreOverlapped( offset1 int64, size1 int64, offset2 int64, size2 int64, ) bool { if offset1 <= offset2 && offset2 <= offset1+size1 { return true } else if offset1 <= offset2+size2 && offset2+size2 <= offset1+size1 { return true } else if offset2 <= offset1 && offset1 <= offset2+size2 { return true } else if offset2 <= offset1+size1 && offset1+size1 <= offset2+size2 { return true } else { return false } } ================================================ FILE: golang_vm/uPIMulator/src/misc/file_dumper.go ================================================ package misc import ( "bufio" "os" ) type FileDumper struct { path string } func (this *FileDumper) Init(path string) { this.path = path } func (this *FileDumper) WriteLines(lines []string) { file, create_err := os.Create(this.path) if create_err != nil { panic(create_err) } writer := bufio.NewWriter(file) for _, line := range lines { _, write_err := writer.WriteString(line + "\n") if write_err != nil { panic(write_err) } } flush_err := writer.Flush() if flush_err != nil { panic(flush_err) } close_err := file.Close() if close_err != nil { panic(close_err) } } ================================================ FILE: golang_vm/uPIMulator/src/misc/file_scanner.go ================================================ package misc import ( "bufio" "os" ) type FileScanner struct { path string } func (this *FileScanner) Init(path string) { this.path = path } func (this *FileScanner) ReadLines() []string { file, open_err := os.Open(this.path) if open_err != nil { panic(open_err) } scanner := bufio.NewScanner(file) lines := make([]string, 0) for scanner.Scan() { lines = append(lines, scanner.Text()) } if scan_err := scanner.Err(); scan_err != nil { panic(scan_err) } if close_err := file.Close(); close_err != nil { panic(close_err) } return lines } ================================================ FILE: golang_vm/uPIMulator/src/misc/stat_factory.go ================================================ package misc import ( "fmt" "slices" ) type StatFactory struct { name string stats map[string]int64 } func (this *StatFactory) Init(name string) { this.name = name this.stats = make(map[string]int64) } func (this *StatFactory) Name() string { return this.name } func (this *StatFactory) Stats() []string { stats := make([]string, 0) for stat, _ := range this.stats { stats = append(stats, stat) } slices.Sort(stats) return stats } func (this *StatFactory) Value(stat string) int64 { return this.stats[stat] } func (this *StatFactory) Increment(stat string, value int64) { this.stats[stat] += value } func (this *StatFactory) ToLines() []string { lines := make([]string, 0) for stat, value := range this.stats { line := fmt.Sprintf("%s_%s: %d", this.name, stat, value) lines = append(lines, line) } return lines } ================================================ FILE: golang_vm/uPIMulator/src/program/app.go ================================================ package program import ( "errors" "fmt" "path/filepath" "strconv" "strings" "uPIMulator/src/host/abi" "uPIMulator/src/misc" ) type App struct { bin_dirpath string benchmark string num_dpus int num_tasklets int labels []*abi.Label } func (this *App) Init(command_line_parser *misc.CommandLineParser) { this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_tasklets = num_channels * num_ranks_per_channel * num_dpus_per_rank this.labels = make([]*abi.Label, 0) this.LoadLabels() } func (this *App) HasLabel(label_name string) bool { for _, label := range this.labels { if label.Name() == label_name { return true } } return false } func (this *App) Label(label_name string) *abi.Label { if !this.HasLabel(label_name) { err_msg := fmt.Sprintf("label (%s) is not found", label_name) err := errors.New(err_msg) panic(err) } for _, label := range this.labels { if label.Name() == label_name { return label } } return nil } func (this *App) LoadLabels() { path := filepath.Join(this.bin_dirpath, "bytecode.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) for _, line := range file_scanner.ReadLines() { if strings.Contains(line, ":") { label_name := line[:len(line)-1] label := new(abi.Label) label.Init(label_name) this.labels = append(this.labels, label) } else { words := strings.Split(line, " ") var op_code abi.OpCode args := make([]int64, 0) strs := make([]string, 0) for i, word := range words { if i == 0 { op_code = this.ConvertToOpCode(word[1:]) } else { if arg, err := strconv.ParseInt(word, 10, 64); err == nil { args = append(args, arg) } else { strs = append(strs, word) } } } bytecode := new(abi.Bytecode) bytecode.Init(op_code, args, strs) this.labels[len(this.labels)-1].Append(bytecode) } } } func (this *App) ConvertToOpCode(op_code string) abi.OpCode { if op_code == "NEW_SCOPE" { return abi.NEW_SCOPE } else if op_code == "DELETE_SCOPE" { return abi.DELETE_SCOPE } else if op_code == "PUSH_CHAR" { return abi.PUSH_CHAR } else if op_code == "PUSH_SHORT" { return abi.PUSH_SHORT } else if op_code == "PUSH_INT" { return abi.PUSH_INT } else if op_code == "PUSH_LONG" { return abi.PUSH_LONG } else if op_code == "PUSH_STRING" { return abi.PUSH_STRING } else if op_code == "POP" { return abi.POP } else if op_code == "BEGIN_STRUCT" { return abi.BEGIN_STRUCT } else if op_code == "APPEND_VOID" { return abi.APPEND_VOID } else if op_code == "APPEND_CHAR" { return abi.APPEND_CHAR } else if op_code == "APPEND_SHORT" { return abi.APPEND_SHORT } else if op_code == "APPEND_INT" { return abi.APPEND_INT } else if op_code == "APPEND_LONG" { return abi.APPEND_LONG } else if op_code == "APPEND_STRUCT" { return abi.APPEND_STRUCT } else if op_code == "END_STRUCT" { return abi.END_STRUCT } else if op_code == "NEW_GLOBAL_VOID" { return abi.NEW_GLOBAL_VOID } else if op_code == "NEW_GLOBAL_CHAR" { return abi.NEW_GLOBAL_CHAR } else if op_code == "NEW_GLOBAL_SHORT" { return abi.NEW_GLOBAL_SHORT } else if op_code == "NEW_GLOBAL_INT" { return abi.NEW_GLOBAL_INT } else if op_code == "NEW_GLOBAL_LONG" { return abi.NEW_GLOBAL_LONG } else if op_code == "NEW_FAST_VOID" { return abi.NEW_FAST_VOID } else if op_code == "NEW_FAST_CHAR" { return abi.NEW_FAST_CHAR } else if op_code == "NEW_FAST_SHORT" { return abi.NEW_FAST_SHORT } else if op_code == "NEW_FAST_INT" { return abi.NEW_FAST_INT } else if op_code == "NEW_FAST_LONG" { return abi.NEW_FAST_LONG } else if op_code == "NEW_FAST_STRUCT" { return abi.NEW_FAST_STRUCT } else if op_code == "NEW_ARG_VOID" { return abi.NEW_ARG_VOID } else if op_code == "NEW_ARG_CHAR" { return abi.NEW_ARG_CHAR } else if op_code == "NEW_ARG_SHORT" { return abi.NEW_ARG_SHORT } else if op_code == "NEW_ARG_INT" { return abi.NEW_ARG_INT } else if op_code == "NEW_ARG_LONG" { return abi.NEW_ARG_LONG } else if op_code == "NEW_ARG_STRUCT" { return abi.NEW_ARG_STRUCT } else if op_code == "NEW_RETURN_VOID" { return abi.NEW_RETURN_VOID } else if op_code == "NEW_RETURN_CHAR" { return abi.NEW_RETURN_CHAR } else if op_code == "NEW_RETURN_SHORT" { return abi.NEW_RETURN_SHORT } else if op_code == "NEW_RETURN_INT" { return abi.NEW_RETURN_INT } else if op_code == "NEW_RETURN_LONG" { return abi.NEW_RETURN_LONG } else if op_code == "NEW_RETURN_STRUCT" { return abi.NEW_RETURN_STRUCT } else if op_code == "SIZEOF_VOID" { return abi.SIZEOF_VOID } else if op_code == "SIZEOF_CHAR" { return abi.SIZEOF_CHAR } else if op_code == "SIZEOF_SHORT" { return abi.SIZEOF_SHORT } else if op_code == "SIZEOF_INT" { return abi.SIZEOF_INT } else if op_code == "SIZEOF_LONG" { return abi.SIZEOF_LONG } else if op_code == "SIZEOF_STRUCT" { return abi.SIZEOF_STRUCT } else if op_code == "GET_IDENTIFIER" { return abi.GET_IDENTIFIER } else if op_code == "GET_ARG_IDENTIFIER" { return abi.GET_ARG_IDENTIFIER } else if op_code == "GET_SUBSCRIPT" { return abi.GET_SUBSCRIPT } else if op_code == "GET_ACCESS" { return abi.GET_ACCESS } else if op_code == "GET_REFERENCE" { return abi.GET_REFERENCE } else if op_code == "GET_ADDRESS" { return abi.GET_ADDRESS } else if op_code == "GET_VALUE" { return abi.GET_VALUE } else if op_code == "ALLOC" { return abi.ALLOC } else if op_code == "FREE" { return abi.FREE } else if op_code == "ASSERT" { return abi.ASSERT } else if op_code == "ADD" { return abi.ADD } else if op_code == "SUB" { return abi.SUB } else if op_code == "MUL" { return abi.MUL } else if op_code == "DIV" { return abi.DIV } else if op_code == "MOD" { return abi.MOD } else if op_code == "LSHIFT" { return abi.LSHIFT } else if op_code == "RSHIFT" { return abi.RSHIFT } else if op_code == "NEGATE" { return abi.NEGATE } else if op_code == "TILDE" { return abi.TILDE } else if op_code == "SQRT" { return abi.SQRT } else if op_code == "BITWISE_AND" { return abi.BITWISE_AND } else if op_code == "BITWISE_XOR" { return abi.BITWISE_XOR } else if op_code == "BITWISE_OR" { return abi.BITWISE_OR } else if op_code == "LOGICAL_AND" { return abi.LOGICAL_AND } else if op_code == "LOGICAL_OR" { return abi.LOGICAL_OR } else if op_code == "LOGICAL_NOT" { return abi.LOGICAL_NOT } else if op_code == "EQ" { return abi.EQ } else if op_code == "NOT_EQ" { return abi.NOT_EQ } else if op_code == "LESS" { return abi.LESS } else if op_code == "LESS_EQ" { return abi.LESS_EQ } else if op_code == "GREATER" { return abi.GREATER } else if op_code == "GREATER_EQ" { return abi.GREATER_EQ } else if op_code == "CONDITIONAL" { return abi.CONDITIONAL } else if op_code == "ASSIGN" { return abi.ASSIGN } else if op_code == "ASSIGN_STAR" { return abi.ASSIGN_STAR } else if op_code == "ASSIGN_DIV" { return abi.ASSIGN_DIV } else if op_code == "ASSIGN_MOD" { return abi.ASSIGN_MOD } else if op_code == "ASSIGN_ADD" { return abi.ASSIGN_ADD } else if op_code == "ASSIGN_SUB" { return abi.ASSIGN_SUB } else if op_code == "ASSIGN_LSHIFT" { return abi.ASSIGN_LSHIFT } else if op_code == "ASSIGN_RSHIFT" { return abi.ASSIGN_RSHIFT } else if op_code == "ASSIGN_BITWISE_AND" { return abi.ASSIGN_BITWISE_AND } else if op_code == "ASSIGN_BITWISE_XOR" { return abi.ASSIGN_BITWISE_XOR } else if op_code == "ASSIGN_BITWISE_OR" { return abi.ASSIGN_BITWISE_OR } else if op_code == "ASSIGN_PLUS_PLUS" { return abi.ASSIGN_PLUS_PLUS } else if op_code == "ASSIGN_MINUS_MINUS" { return abi.ASSIGN_MINUS_MINUS } else if op_code == "ASSIGN_RETURN" { return abi.ASSIGN_RETURN } else if op_code == "JUMP" { return abi.JUMP } else if op_code == "JUMP_IF_ZERO" { return abi.JUMP_IF_ZERO } else if op_code == "JUMP_IF_NONZERO" { return abi.JUMP_IF_NONZERO } else if op_code == "CALL" { return abi.CALL } else if op_code == "RETURN" { return abi.RETURN } else if op_code == "NOP" { return abi.NOP } else if op_code == "DPU_ALLOC" { return abi.DPU_ALLOC } else if op_code == "DPU_LOAD" { return abi.DPU_LOAD } else if op_code == "DPU_PREPARE" { return abi.DPU_PREPARE } else if op_code == "DPU_TRANSFER" { return abi.DPU_TRANSFER } else if op_code == "DPU_COPY_TO" { return abi.DPU_COPY_TO } else if op_code == "DPU_COPY_FROM" { return abi.DPU_COPY_FROM } else if op_code == "DPU_LAUNCH" { return abi.DPU_LAUNCH } else if op_code == "DPU_FREE" { return abi.DPU_FREE } else { err_msg := fmt.Sprintf("op code (%s) is not valid", op_code) err := errors.New(err_msg) panic(err) } } ================================================ FILE: golang_vm/uPIMulator/src/program/task.go ================================================ package program import ( "errors" "path/filepath" "strconv" "strings" "uPIMulator/src/encoding" "uPIMulator/src/misc" ) type Task struct { bin_dirpath string benchmark string num_dpus int num_tasklets int addresses map[string]int64 values map[string]int64 atomic *encoding.ByteStream iram *encoding.ByteStream wram *encoding.ByteStream mram *encoding.ByteStream } func (this *Task) Init(command_line_parser *misc.CommandLineParser) { this.bin_dirpath = command_line_parser.StringParameter("bin_dirpath") this.benchmark = command_line_parser.StringParameter("benchmark") num_channels := int(command_line_parser.IntParameter("num_channels")) num_ranks_per_channel := int(command_line_parser.IntParameter("num_ranks_per_channel")) num_dpus_per_rank := int(command_line_parser.IntParameter("num_dpus_per_rank")) this.num_tasklets = num_channels * num_ranks_per_channel * num_dpus_per_rank this.InitAddresses() this.InitValues() this.InitAtomic() this.InitIram() this.InitWram() this.InitMram() } func (this *Task) InitAddresses() { path := filepath.Join(this.bin_dirpath, "addresses.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() this.addresses = make(map[string]int64) for _, line := range lines { words := strings.Split(line, ":") name := words[0] address, err := strconv.ParseInt(words[1][1:], 10, 64) if err != nil { panic(err) } this.addresses[name] = address } } func (this *Task) InitValues() { path := filepath.Join(this.bin_dirpath, "values.txt") file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() this.values = make(map[string]int64) for _, line := range lines { words := strings.Split(line, ":") name := words[0] address, err := strconv.ParseInt(words[1][1:], 10, 64) if err != nil { panic(err) } this.values[name] = address } } func (this *Task) InitAtomic() { path := filepath.Join(this.bin_dirpath, "atomic.bin") this.atomic = this.InitByteStream(path) } func (this *Task) InitIram() { path := filepath.Join(this.bin_dirpath, "iram.bin") this.iram = this.InitByteStream(path) } func (this *Task) InitWram() { path := filepath.Join(this.bin_dirpath, "wram.bin") this.wram = this.InitByteStream(path) } func (this *Task) InitMram() { path := filepath.Join(this.bin_dirpath, "mram.bin") this.mram = this.InitByteStream(path) } func (this *Task) InitByteStream(path string) *encoding.ByteStream { file_scanner := new(misc.FileScanner) file_scanner.Init(path) lines := file_scanner.ReadLines() byte_stream := new(encoding.ByteStream) byte_stream.Init() for _, line := range lines { value, err := strconv.Atoi(line) if err != nil { panic(err) } byte_stream.Append(uint8(value)) } return byte_stream } func (this *Task) Atomic() *encoding.ByteStream { return this.atomic } func (this *Task) Iram() *encoding.ByteStream { return this.iram } func (this *Task) Wram() *encoding.ByteStream { return this.wram } func (this *Task) Mram() *encoding.ByteStream { return this.mram } func (this *Task) Addresses() map[string]int64 { return this.addresses } func (this *Task) Values() map[string]int64 { return this.values } func (this *Task) SysUsedMramEnd() int64 { if _, found := this.values["__sys_used_mram_end"]; !found { err := errors.New("__sys_used_mram_end is not found") panic(err) } return this.values["__sys_used_mram_end"] } func (this *Task) SysEnd() int64 { if _, found := this.addresses["__sys_end"]; !found { err := errors.New("__sys_end is not found") panic(err) } return this.addresses["__sys_end"] } ================================================ FILE: golang_vm/uPIMulator/src/system/system.go ================================================ package system import ( "uPIMulator/src/host/vm" "uPIMulator/src/misc" "uPIMulator/src/program" ) type System struct { vm *vm.VirtualMachine } func (this *System) Init(command_line_parser *misc.CommandLineParser) { this.vm = new(vm.VirtualMachine) this.vm.Init(command_line_parser) } func (this *System) Fini() { this.vm.Fini() } func (this *System) Simulate(app *program.App, task *program.Task) { this.vm.Load(app, task) for this.vm.CanAdvance() { this.vm.Advance() } } func (this *System) Dump() { this.vm.Dump() } ================================================ FILE: python_cpp/README.md ================================================ # ⚙️ Usage ## Currently Supported Mode uPIMulator operates in an execution-driven simulation mode, enabling cycle-accurate performance analysis of PIM-based applications. ## Workflow The typical usage workflow comprises two primary stages: 1. **Binary Generation:** Compile, assemble, and link your application code to generate the required binary files for simulation. 2. **Cycle-Level Simulation:** Utilize the generated binary files as input to the cycle-level simulator to obtain detailed performance metrics and insights. We aim to expand uPIMulator's capabilities and may introduce additional usage modes in future releases. ## Installation & Build ### Prerequisites - **Python:** Python 3.10 or higher - **C++ Compiler:** C++20 compliant compiler - **CMake:** CMake 3.16 or higher - **Docker:** Docker Engine - **User Permissions:** Your Ubuntu user account must be a member of the `docker` group. - **Operating System:** Ubuntu 18.04 or later (recommended) - **Environment Management (Optional):** We recommend using a tool like [Anaconda](https://www.anaconda.com/) for managing your Python environment. ### Installation Steps 1. **Install Linker Dependencies:** Navigate to the `uPIMulator_frontend` directory and install the required Python packages using `pip`: ```bash cd /path/to/uPIMulator/python_cpp/uPIMulator_frontend pip install -r requirements.txt ``` 2. **Build the Cycle-level Simulator:** Navigate to the `uPIMulator_backend/script` directory and execute the build script: ```bash cd /path/to/uPIMulator/python_cpp/uPIMulator_backend/script sh build.sh ``` > **Note:** Replace `/path/to/uPIMulator` with the actual path to your uPIMulator repository. If you encounter any issues during the installation or build process, please refer to the troubleshooting section in the documentation or open an issue on our GitHub repository. ## Binary Files Generation We will use the VA (vector addition) benchmark as an example to demonstrate the binary file generation phase. After compiling, assembling, and linking, you will find the generated binary files within the `uPIMulator_frontend/bin` directory. > **Pre-Generated Binaries:** To expedite the setup process, you can utilize our pre-generated binary files available at the following [link](https://drive.google.com/file/d/1kfL-xGn1F18Ezmw81IvAhxEaLiZZOLFR/view?usp=sharing). ### Compilation ```bash cd /path/to/uPIMulator/python_cpp/uPIMulator_frontend/src python main.py --mode compile --num_tasklets 16 --benchmark VA --num_dpus 1 ``` ### Assembly and Linking ```bash cd /path/to/uPIMulator/python_cpp/uPIMulator_frontend/src python main.py --mode link --num_tasklets 16 --benchmark VA --data_prep_param 1024 --num_dpus 1 ``` > **Troubleshooting:** In the event that the linking command encounters errors, please execute the following Docker build command and then reattempt the compilation and linking steps: ```bash docker build -t bongjoonhyun/compiler -f /path/to/uPIMulator/python_cpp/uPIMulator_frontend/docker/compiler.dockerfile . ``` > **Supported Benchmarks and Performance Note:** uPIMulator currently supports 13 PrIM benchmarks. > Please be aware that the initial compile/assemble/link process may take approximately 30 minutes. ## Cycle-level Simulation ### Executing a Simulation Initiate a cycle-level simulation by providing the following inputs to the `uPIMulator` executable: - Benchmark name - Number of tasklets - Absolute path to the directory containing the generated binary files (`bindir`) You can further customize the simulation behavior using various command-line options. ### Simulation Output The simulation results will be printed directly to the standard output (`stdout`). ### Example Command ```bash cd /path/to/uPIMulator/uPIMulator_backend/build/ ./src/uPIMulator --benchmark VA --num_tasklets 16 --bindir /path/to/uPIMulator/uPIMulator_frontend/bin/1_dpus/ --logdir . ``` > **Important Note:** Ensure that you provide the absolute path to the `bindir` when executing the simulation. Feel free to explore different benchmark configurations and utilize the command-line options to tailor the simulation to your specific requirements. # 📄 Reproducing Figures from the Paper This section provides instructions for replicating the figures presented in our paper. We offer detailed replication manuals for figures used in **Section 4 (Demystifying UPMEM-PIM with uPIMulator)**. Please note that Figure 8 is omitted for brevity. ## Configuration of PrIM Benchmarks - **Single DPU Focus:** For Figures 5, 6, 7, and 9, the `num_dpus` parameter must always be set to `1`, as these experiments specifically characterize the behavior of a single DPU. - **Data Preparation Parameter:** When generating the binary files for the PrIM benchmarks, please configure the `data_prep_param` parameter according to the following table: | Benchmark | `data_prep_param` (Figures 5, 6, 7, 9) | `data_prep_param` (Figure 10) | |---|---|---| | BS | 32768 | 131072 | | GEMV | 2048 | 4096 | | HST-L | 131072 | 524288 | | HST-S | 131072 | 524288 | | MLP | 256 | 1024 | | RED | 524288 | 2097152| | SCAN-RSS | 262144 | 1048576| | SCAN-SSA | 262144 | 1048576| | SEL | 524288 | 2097152| | TRNS | 1024 | 128 | | TS | 2048 | 65536 | | UNI | 524288 | 2097152| | VA | 524288 | 2097152| ## Example Command ```bash python main.py --mode link --num_tasklets 16 --benchmark VA --data_prep_param 524288 --num_dpus 1 ``` Please ensure you adhere to these configurations to accurately replicate the figures presented in the paper. ## Figure 5: PrIM Compute and Memory Utilization This figure illustrates the compute utilization (red points) and memory read bandwidth utilization (blue points) of the PrIM benchmarks when executed with 1, 4, and 16 threads (tasklets). ### Calculation Formulas - **Compute Utilization (IPC):** `num_instructions` / (`logic_cycle` - `communication_cycle`) - **Memory Read Bandwidth Utilization (GB/s):** Please refer to the provided Excel sheet for the calculation at the following [link](../assets/figure5_mem_util_calculator.xlsx) > **Note:** The required values for these calculations can be obtained from the simulation results generated by uPIMulator. ## Figure 6: DPU Runtime Breakdown This figure presents a breakdown of DPU runtime, categorizing cycles into active (black) and various idle states (red, yellow, blue). The following formulas can be used to calculate the proportions of each category: ### Calculation Formulas - **Issuable Ratio:** `breakdown_run` / (`logic_cycle` - `communication_cycle`) - **Idle (Memory) Ratio:** `breakdown_dma` / (`logic_cycle` - `communication_cycle`) - **Idle (Revolver) Ratio:** (`breakdown_etc` - `communication_cycle`) / (`logic_cycle` - `communication_cycle`) - **Idle (RF) Ratio:** `backpressuer` / (`logic_cycle` - `communication_cycle`) > **Note:** The values for the variables in these formulas (e.g., `breakdown_run`, `logic_cycle`) can be extracted from the simulation results generated by uPIMulator. ## Figure 7: Issuable Tasklets Figure 7 visualizes the number of tasklets (threads) that are ready for execution (issuable) by the DPU scheduler at each cycle. ### Replication To reproduce this figure, utilize the provided [Excel sheet](../assets/figure7_active_tasklet_breakdown.xlsx). The spreadsheet includes instructions on how to populate it with the relevant simulation output data, and it will automatically generate the corresponding figure. > **Important Configuration Note:** Please ensure that the number of threads is configured to **16 tasklets** when running the simulations for this figure. > You can achieve this by using the following command-line argument: `--num_tasklets 16`. ## Figure 9: Instruction Mix (Single DPU) Figure 9 provides a breakdown of the instruction mix observed during single-DPU execution. To generate this figure, follow the steps outlined below using the `upmem_profiler` tool and the accompanying Excel sheet. ### Procedure 1. **Build the Profiler** ```bash cd /path/to/uPIMulator/tools/upmem_profiler/script bash build.sh ``` 2. **Extract Instructions** Run the simulation with the `--verbose 1` flag to capture detailed instruction traces. ```bash cd /path/to/uPIMulator/python_cpp/uPIMulator_backend/ ./build/src/uPIMulator --benchmark VA --num_tasklets 16 --bindir /path/to/uPIMulator/python_cpp/uPIMulator_frontend/bin/1_dpus/ --logdir . --verbose 1 > trace.txt ``` 3. **Run the Profiler** Process the generated trace file using the `upmem_profiler` in `instruction_mix` mode. ```bash cd /path/to/uPIMulator/tools/upmem_profiler/ ./build/src/upmem_profiler --logpath /path/to/uPIMulator/python_cpp/uPIMulator_backend/trace.txt --mode instruction_mix ``` 4. **Generate the Figure** Utilize the profiler's output to populate the provided [Excel sheet](../assets/figure9_instruction_mix.xlsx), which will automatically generate the instruction mix figure. > **Important Configuration Note:** Similar to Figure 7, the instruction mix analysis in Figure 9 is based on simulations with **16 tasklets**. > Ensure that you maintain this configuration (`--num_tasklets 16`) for accurate replication. ## Figure 10: Multi-DPU Latency Breakdown and Speedup Figure 10 presents the latency breakdown and speedup achieved in multi-DPU scenarios. ### Configuring the Number of DPUs You can adjust the number of DPUs by modifying the `num_dpus` parameter in both the `uPIMulator_frontend` and `uPIMulator_backend`. ### Generating the Latency Breakdown To obtain the latency breakdown data for plotting, utilize the `upmem_reg_model` tool located in the `tools/upmem_reg_model/` directory. This tool implements a communication model between the host and DPUs based on linear regression. ### Procedure 1. **Prepare Input Excel:** - We provide a sample input Excel file as a template. - Append a new row to this file, specifying the benchmark name, number of DPUs, and the `data_prep_param` used in your simulation. - Fill in the relevant time values (in milliseconds) obtained from your simulation results, such as kernel execution time. 2. **Run the Regression Model:** ```bash cd /path/to/uPIMulator/tools/upmem_reg_model/src python main.py --input_excel_filepath /path/to/your/input_excel_file --output_excel_filepath /path/to/your/output_excel_file ``` 3. **Access the Output:** - The linear regression results will be available in the specified output Excel file. - Use this data to create the latency breakdown plots as shown in Figure 10. Please ensure that you follow these steps carefully to accurately reproduce the multi-DPU latency breakdown and speedup analysis presented in the paper. # 🌋 Adding Custom Benchmarks uPIMulator empowers you to go beyond the provided PrIM benchmark suite by incorporating your own custom benchmarks. This is particularly beneficial if you have access to UPMEM-PIM hardware and want to evaluate your code's performance in a simulated environment. ## Requirements To successfully integrate a new benchmark, ensure it adheres to the following: 1. **UPMEM-C Language:** The benchmark must be implemented in UPMEM-C, a C-like language tailored for UPMEM-PIM programming. Consult the [UPMEM SDK documentation](https://sdk.upmem.com/2021.4.0/) for detailed programming guidelines. 2. **File Structure and Naming:** - Maintain the same file hierarchy as the PrIM benchmarks, including a `dpu` subdirectory. - Utilize the same `Makefile` structure used by the PrIM suite for automated compilation. 3. **Communication Variables:** - **Host-to-DPU:** Use the `DPU_INPUT_ARGUMENTS` variable for data transfer from the host to DPUs via WRAM. - **DPU-to-Host:** Use the `DPU_RESULTS` variable for data transfer from DPUs to the host via WRAM. > **Important:** Deviating from these variable names will result in the linker ignoring the communication during the linking phase. ## Data Preparation Once your benchmark meets the above criteria, it's ready for data input. Since UPMEM PIM-enabled memory directly utilizes physical addresses, exercise caution when feeding input/output data. You'll need to provide a Python script to handle data preparation for your benchmark. This script should reside in the `uPIMulator_frontend/src/assembler/data_prep` directory and be recognized by `uPIMulator_frontend/src/assembler/assembler.py`. > **Key Considerations for Data Preparation Scripts: > - Data transferred from the host to DPUs using `dpu_push_xfer` must be organized within the `input_dpu_mram_heap_pointer_name` variable in your data preparation script. > - Similarly, data transferred from DPUs to the host using `dpu_push_xfer` should be placed within the `output_dpu_mram_heap_pointer_name` variable. ## Reference Examples We have included data preparation scripts for the 13 supported PrIM benchmarks. These serve as excellent references for structuring your custom data preparation scripts. By following these guidelines, you can seamlessly integrate your benchmarks into uPIMulator for comprehensive performance evaluation and analysis. If you have any questions or encounter any difficulties during the integration process, contact us with any questions or difficulties. ================================================ FILE: python_cpp/uPIMulator_backend/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) #set(CMAKE_CXX_COMPILER "/opt/rh/devtoolset-8/root/usr/bin/g++") #set(CMAKE_CXX_COMPILER "/usr/bin/g++-8") set(CMAKE_CXX_COMPILER "/usr/bin/g++") set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS "-O3") #set(CMAKE_CXX_FLAGS "-g") link_libraries(stdc++fs) project(uPIMulator) add_subdirectory(src) ================================================ FILE: python_cpp/uPIMulator_backend/script/build.sh ================================================ #!/bin/bash mkdir -p ../build cd ../build || exit # shellcheck disable=SC2035 rm -rf * cmake .. make -j cd - || exit ================================================ FILE: python_cpp/uPIMulator_backend/script/format.sh ================================================ #!/bin/bash cd ../lib find . -regex '.*\.\(cpp\|hpp\|cc\|h\)' -exec clang-format -style=Google -i {} \; cd - cd ../src find . -regex '.*\.\(cpp\|hpp\|cc\|h\)' -exec clang-format -style=Google -i {} \; cd - ================================================ FILE: python_cpp/uPIMulator_backend/script/run.sh ================================================ #/bin/bash num_dpus=$1 benchmark=$2 data_size=$3 eval "mkdir -p /home/dongjae/pimulator/new_experiment_result/multi_dpus/trace/${benchmark}/${data_size}/${num_dpus}_dpus" echo "${benchmark} - ${data_size}" eval "mkdir -p /home/dongjae/pimulator/new_experiment_result/multi_dpus/log/${benchmark}/${data_size}/${num_dpus}_dpus/${benchmark}.16." sim_name="/home/dongjae/pimulator/simulator/upmem_sim_multi_dpus/build/src/upmem_sim" bin_dir="/home/dongjae/pimulator/bin_files/bin_multi/${benchmark}/${data_size}/${num_dpus}_dpus/" log_dir="/home/dongjae/pimulator/new_experiment_result/multi_dpus/log/${benchmark}/${data_size}/${num_dpus}_dpus/${benchmark}.16." # Note that you should add '/' at the last position log_path="/home/dongjae/pimulator/new_experiment_result/multi_dpus/trace/${benchmark}/${data_size}/${num_dpus}_dpus/" cmd="nohup ${sim_name} --benchmark ${benchmark} --num_tasklets 16 --bindir ${bin_dir} --logdir ${log_dir} --num_dpus ${num_dpus} 1> ${log_path}/${benchmark}.16.trace &" echo ${cmd} eval ${cmd} ================================================ FILE: python_cpp/uPIMulator_backend/script/run_serial.sh ================================================ #/bin/bash num_dpus=$1 benchmark=$2 data_size=$3 echo "${benchmark} - ${data_size}" eval "mkdir -p /home/dongjae/pimulator/hpca_2024_log/multi_dpus_validation/${benchmark}/${data_size}/${num_dpus}_dpus/${benchmark}.16." sim_name="/home/dongjae/pimulator/simulator/upmem_sim_multi_dpus/build/src/upmem_sim" bin_dir="/home/dongjae/pimulator/bin_files_validation/bin_multi/${benchmark}/${data_size}/${num_dpus}_dpus/" log_dir="/home/dongjae/pimulator/hpca_2024_log/multi_dpus_validation/${benchmark}/${data_size}/${num_dpus}_dpus/${benchmark}.16." # Note that you should add '/' at the last position cmd="nohup ${sim_name} --benchmark ${benchmark} --num_tasklets 16 --bindir ${bin_dir} --logdir ${log_dir} --num_dpus ${num_dpus}" echo ${cmd} eval ${cmd} ================================================ FILE: python_cpp/uPIMulator_backend/src/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16) include_directories(.) file(GLOB_RECURSE SRCS *.cc) add_executable(uPIMulator ${SRCS}) ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/_base_cc.cc ================================================ #include "_base_cc.h" #include namespace upmem_sim::abi::cc { _BaseCC::_BaseCC(std::set conditions, isa::Condition condition) : condition_(condition) { assert(conditions.count(condition) != 0); } } // namespace upmem_sim::abi::cc ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/_base_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC__BASE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC__BASE_CC_H_ #include #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class _BaseCC { public: explicit _BaseCC(std::set conditions, isa::Condition condition); ~_BaseCC() = default; isa::Condition condition() { return condition_; } private: isa::Condition condition_; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/acquire_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_ACQUIRE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_ACQUIRE_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class AcquireCC : public _BaseCC { public: explicit AcquireCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::TRUE}, condition) {} ~AcquireCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/add_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_ADD_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_ADD_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class AddNZCC : public _BaseCC { public: explicit AddNZCC(isa::Condition condition) : _BaseCC({isa::C, isa::NC, isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::OV, isa::NOV, isa::PL, isa::MI, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::NC5, isa::NC6, isa::NC7, isa::NC8, isa::NC9, isa::NC10, isa::NC11, isa::NC12, isa::NC13, isa::NC14, isa::TRUE}, condition) {} ~AddNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/boot_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_BOOT_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_BOOT_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class BootCC : public _BaseCC { public: explicit BootCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::TRUE, isa::FALSE}, condition) {} ~BootCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/const_cc_ge0.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_CONST_CC_GE0_H_ #define UPMEM_SIM_ABI_ISA_CC_CONST_CC_GE0_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ConstCCGE0 : public _BaseCC { public: explicit ConstCCGE0(isa::Condition condition) : _BaseCC({isa::PL}, condition) {} ~ConstCCGE0() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/const_cc_geu.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_CONST_CC_GEU_H_ #define UPMEM_SIM_ABI_ISA_CC_CONST_CC_GEU_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ConstCCGEU : public _BaseCC { public: explicit ConstCCGEU(isa::Condition condition) : _BaseCC({isa::GEU}, condition) {} ~ConstCCGEU() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/const_cc_zero.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_CONST_CC_ZERO_H_ #define UPMEM_SIM_ABI_ISA_CC_CONST_CC_ZERO_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ConstCCZero : public _BaseCC { public: explicit ConstCCZero(isa::Condition condition) : _BaseCC({isa::Z}, condition) {} ~ConstCCZero() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/count_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_COUNT_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_COUNT_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class CountNZCC : public _BaseCC { public: explicit CountNZCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::MAX, isa::NMAX, isa::TRUE}, condition) {} ~CountNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/div_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_DIV_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_DIV_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class DivCC : public _BaseCC { public: explicit DivCC(isa::Condition condition) : _BaseCC({isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::TRUE, isa::FALSE}, condition) {} ~DivCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/div_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_DIV_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_DIV_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class DivNZCC : public _BaseCC { public: explicit DivNZCC(isa::Condition condition) : _BaseCC({isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::TRUE}, condition) { } ~DivNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/ext_sub_set_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_EXT_SUB_SET_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_EXT_SUB_SET_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ExtSubSetCC : public _BaseCC { public: explicit ExtSubSetCC(isa::Condition condition) : _BaseCC({isa::C, isa::NC, isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::OV, isa::NOV, isa::EQ, isa::NEQ, isa::PL, isa::MI, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::GES, isa::GEU, isa::GTS, isa::GTU, isa::LES, isa::LEU, isa::LTS, isa::LTU, isa::XGTS, isa::XGTU, isa::XLES, isa::XLEU, isa::TRUE}, condition) {} ~ExtSubSetCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/false_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_FALSE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_FALSE_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class FalseCC : public _BaseCC { public: explicit FalseCC(isa::Condition condition) : _BaseCC({isa::FALSE}, condition) {} ~FalseCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/imm_shift_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_IMM_SHIFT_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_IMM_SHIFT_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ImmShiftNZCC : public _BaseCC { public: explicit ImmShiftNZCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::E, isa::O, isa::PL, isa::MI, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::SE, isa::SO, isa::TRUE}, condition) {} ~ImmShiftNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/log_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_LOG_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_LOG_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class LogNZCC : public _BaseCC { public: explicit LogNZCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::PL, isa::MI, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::TRUE}, condition) {} ~LogNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/log_set_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_LOG_SET_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_LOG_SET_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class LogSetCC : public _BaseCC { public: explicit LogSetCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ}, condition) {} ~LogSetCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/mul_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_MUL_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_MUL_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class MulNZCC : public _BaseCC { public: explicit MulNZCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::SZ, isa::SNZ, isa::SPL, isa::SMI, isa::LARGE, isa::SMALL, isa::TRUE}, condition) {} ~MulNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/no_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_NO_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_NO_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class NoCC : public _BaseCC { public: explicit NoCC(isa::Condition condition) : _BaseCC({}, condition) {} ~NoCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/release_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_RELEASE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_RELEASE_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ReleaseCC : public _BaseCC { public: explicit ReleaseCC(isa::Condition condition) : _BaseCC({isa::NZ}, condition) {} ~ReleaseCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/shift_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_SHIFT_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_SHIFT_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class ShiftNZCC : public _BaseCC { public: explicit ShiftNZCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::E, isa::O, isa::PL, isa::MI, isa::SZ, isa::SNZ, isa::SE, isa::SO, isa::SPL, isa::SMI, isa::SH32, isa::NSH32, isa::TRUE}, condition) {} ~ShiftNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/sub_nz_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_SUB_NZ_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_SUB_NZ_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class SubNZCC : public _BaseCC { public: explicit SubNZCC(isa::Condition condition) : _BaseCC({isa::C, isa::NC, isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::OV, isa::NOV, isa::MI, isa::PL, isa::EQ, isa::NEQ, isa::SPL, isa::SMI, isa::GES, isa::GEU, isa::GTS, isa::GTU, isa::LES, isa::LEU, isa::LTS, isa::LTU, isa::XGTS, isa::XGTU, isa::XLES, isa::XLEU, isa::TRUE}, condition) {} ~SubNZCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/sub_set_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_SUB_SET_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_SUB_SET_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class SubSetCC : public _BaseCC { public: explicit SubSetCC(isa::Condition condition) : _BaseCC({isa::Z, isa::NZ, isa::XZ, isa::XNZ, isa::EQ, isa::NEQ}, condition) {} ~SubSetCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/true_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_TRUE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_TRUE_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class TrueCC : public _BaseCC { public: explicit TrueCC(isa::Condition condition) : _BaseCC({isa::TRUE}, condition) {} ~TrueCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/cc/true_false_cc.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_CC_TRUE_FALSE_CC_H_ #define UPMEM_SIM_ABI_ISA_CC_TRUE_FALSE_CC_H_ #include "_base_cc.h" #include "abi/isa/condition.h" namespace upmem_sim::abi::cc { class TrueFalseCC : public _BaseCC { public: explicit TrueFalseCC(isa::Condition condition) : _BaseCC({isa::TRUE, isa::FALSE}, condition) {} ~TrueFalseCC() = default; }; } // namespace upmem_sim::abi::cc #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/instruction/instruction.cc ================================================ #include "instruction.h" #include #include "abi/cc/acquire_cc.h" #include "abi/cc/add_nz_cc.h" #include "abi/cc/boot_cc.h" #include "abi/cc/count_nz_cc.h" #include "abi/cc/div_cc.h" #include "abi/cc/div_nz_cc.h" #include "abi/cc/ext_sub_set_cc.h" #include "abi/cc/false_cc.h" #include "abi/cc/imm_shift_nz_cc.h" #include "abi/cc/log_nz_cc.h" #include "abi/cc/log_set_cc.h" #include "abi/cc/mul_nz_cc.h" #include "abi/cc/release_cc.h" #include "abi/cc/shift_nz_cc.h" #include "abi/cc/sub_nz_cc.h" #include "abi/cc/sub_set_cc.h" #include "abi/cc/true_cc.h" #include "abi/cc/true_false_cc.h" namespace upmem_sim::abi::instruction { Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); if (suffix_ == RICI) { init_rici(ra, imm, condition, pc); } else if (suffix_ == ZRICI) { init_zrici(ra, imm, condition, pc); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rri(rc, ra, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); if (suffix_ == RRIC) { init_rric(rc, ra, imm, condition); } else if (suffix_ == RRIF) { init_rrif(rc, ra, imm, condition); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rrici(rc, ra, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_rrr(rc, ra, rb); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_rrrc(rc, ra, rb, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_rrrci(rc, ra, rb, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zri(ra, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); if (suffix_ == ZRIC) { init_zric(ra, imm, condition); } else if (suffix_ == ZRIF) { init_zrif(ra, imm, condition); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); init_zrr(ra, rb); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); init_zrrc(ra, rb, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); init_zrrci(ra, rb, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rri(dc, ra, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); if (suffix == S_RRIC or suffix == U_RRIC) { init_s_rric(dc, ra, imm, condition); } else if (suffix == S_RRIF or suffix == U_RRIF) { init_s_rrif(dc, ra, imm, condition); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rrici(dc, ra, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_s_rrr(dc, ra, rb); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_s_rrrc(dc, ra, rb, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_s_rrrci(dc, ra, rb, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rr(rc, ra); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rrc(rc, ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rrci(rc, ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zr(ra); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zrc(ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zrci(ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rr(dc, ra); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rrc(dc, ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rrci(dc, ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::PairReg *db, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(db != nullptr); init_drdici(dc, ra, db, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_rrri(rc, ra, rb, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_rrrici(rc, ra, rb, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); if (suffix == ZRRI) { init_zrri(ra, rb, imm); } else if (suffix == DMA_RRI) { init_dma_rri(ra, rb, imm); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); init_zrrici(ra, rb, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_s_rrri(dc, ra, rb, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); assert(rb != nullptr); init_s_rrrici(dc, ra, rb, imm, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rir(rc, imm, ra); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rirc(rc, imm, ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_rirci(rc, imm, ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zir(imm, ra); } Instruction::Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zirc(imm, ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_zirci(imm, ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rirc(dc, imm, ra, condition); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); init_s_rirci(dc, imm, ra, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); init_r(rc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); init_rci(rc, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { init_z(); } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { if (suffix == ZCI) { init_zci(condition, pc); } else if (suffix == CI) { init_ci(condition, pc); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); init_s_r(dc); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); init_s_rci(dc, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { init_i(imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::PairReg *db, isa::Condition condition, int64_t pc) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(db != nullptr); init_ddci(dc, db, condition, pc); } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::GPReg *rc, reg::SrcReg *ra, int64_t off) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(rc != nullptr); assert(ra != nullptr); init_erri(endian, rc, ra, off); } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(dc != nullptr); assert(ra != nullptr); if (suffix == S_ERRI or suffix == U_ERRI) { init_s_erri(endian, dc, ra, off); } else if (suffix == EDRI) { init_edri(endian, dc, ra, off); } else { throw std::invalid_argument(""); } } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, int64_t imm) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); init_erii(endian, ra, off, imm); } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::SrcReg *rb) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(rb != nullptr); init_erir(endian, ra, off, rb); } Instruction::Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::PairReg *db) : op_code_(op_code), suffix_(suffix), rc_(nullptr), ra_(nullptr), rb_(nullptr), dc_(nullptr), db_(nullptr), condition_(nullptr), imm_(nullptr), off_(nullptr), pc_(nullptr), endian_(nullptr), thread_(nullptr) { assert(ra != nullptr); assert(db != nullptr); init_erid(endian, ra, off, db); } Instruction::~Instruction() { delete rc_; delete dc_; delete db_; delete condition_; delete imm_; delete off_; delete pc_; delete endian_; } reg::GPReg *Instruction::rc() { assert(rc_ != nullptr); return rc_; } reg::SrcReg *Instruction::ra() { assert(ra_ != nullptr); return ra_; } reg::SrcReg *Instruction::rb() { assert(rb_ != nullptr); return rb_; } reg::PairReg *Instruction::dc() { assert(dc_ != nullptr); return dc_; } reg::PairReg *Instruction::db() { assert(db_ != nullptr); return db_; } isa::Condition Instruction::condition() { assert(condition_ != nullptr); return *condition_; } abi::word::Immediate *Instruction::imm() { assert(imm_ != nullptr); return imm_; } abi::word::Immediate *Instruction::off() { assert(off_ != nullptr); return off_; } abi::word::Immediate *Instruction::pc() { assert(pc_ != nullptr); return pc_; } isa::Endian Instruction::endian() { assert(endian_ != nullptr); return *endian_; } simulator::dpu::Thread *Instruction::thread() { assert(thread_ != nullptr); return thread_; } void Instruction::set_thread(simulator::dpu::Thread *thread) { assert(thread != nullptr); assert(thread_ == nullptr); thread_ = thread; } void Instruction::init_rici(reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rici_op_codes().count(op_code_)); assert(suffix_ == RICI); ra_ = ra; imm_ = new word::Immediate(word::SIGNED, 16, imm); if (Instruction::acquire_rici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AcquireCC(condition).condition()); } else if (Instruction::release_rici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ReleaseCC(condition).condition()); } else if (Instruction::boot_rici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::BootCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_rri(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm) { assert(Instruction::rri_op_codes().count(op_code_)); assert(suffix_ == RRI); rc_ = rc; ra_ = ra; if (Instruction::add_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 32, imm); } else if (Instruction::asr_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else if (Instruction::call_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 24, imm); } else { throw std::invalid_argument(""); } } void Instruction::init_rric(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rric_op_codes().count(op_code_)); assert(suffix_ == RRIC); rc_ = rc; ra_ = ra; if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::sub_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 24, imm); } else if (Instruction::asr_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::asr_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::sub_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_rrici(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrici_op_codes().count(op_code_)); assert(suffix_ == RRICI); rc_ = rc; ra_ = ra; if (Instruction::add_rrici_op_codes().count(op_code_) or Instruction::and_rrici_op_codes().count(op_code_) or Instruction::sub_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 8, imm); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ImmShiftNZCC(condition).condition()); } else if (Instruction::sub_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_rrif(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rrif_op_codes().count(op_code_)); assert(suffix_ == RRIF); rc_ = rc; ra_ = ra; imm_ = new word::Immediate(word::SIGNED, 24, imm); condition_ = new isa::Condition(cc::FalseCC(condition).condition()); } void Instruction::init_rrr(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb) { assert(Instruction::rrr_op_codes().count(op_code_)); assert(suffix_ == RRR); rc_ = rc; ra_ = ra; rb_ = rb; } void Instruction::init_rrrc(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) { assert(Instruction::rrrc_op_codes().count(op_code_)); assert(suffix_ == RRRC); rc_ = rc; ra_ = ra; rb_ = rb; if (Instruction::add_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::rsub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } else if (Instruction::sub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_rrrci(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) { assert(Instruction::rrrci_op_codes().count(op_code_)); assert(suffix_ == RRRCI); rc_ = rc; ra_ = ra; rb_ = rb; if (Instruction::add_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ShiftNZCC(condition).condition()); } else if (Instruction::mul_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::MulNZCC(condition).condition()); } else if (Instruction::rsub_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_zri(reg::SrcReg *ra, int64_t imm) { assert(Instruction::rri_op_codes().count(op_code_)); assert(suffix_ == ZRI); ra_ = ra; if (Instruction::add_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 32, imm); } else if (Instruction::asr_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else if (Instruction::call_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 28, imm); } else { throw std::invalid_argument(""); } } void Instruction::init_zric(reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rric_op_codes().count(op_code_)); assert(suffix_ == ZRIC); ra_ = ra; if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::sub_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 27, imm); } else if (Instruction::asr_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::asr_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::sub_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_zrici(reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrrci_op_codes().count(op_code_)); assert(suffix_ == ZRICI); ra_ = ra; if (Instruction::add_rrici_op_codes().count(op_code_) or Instruction::and_rrici_op_codes().count(op_code_) or Instruction::sub_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 11, imm); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ImmShiftNZCC(condition).condition()); } else if (Instruction::sub_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_zrif(reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rrif_op_codes().count(op_code_)); assert(suffix_ == ZRIF); ra_ = ra; imm_ = new word::Immediate(word::SIGNED, 27, imm); condition_ = new isa::Condition(cc::FalseCC(condition).condition()); } void Instruction::init_zrr(reg::SrcReg *ra, reg::SrcReg *rb) { assert(Instruction::rrr_op_codes().count(op_code_)); assert(suffix_ == ZRR); ra_ = ra; rb_ = rb; } void Instruction::init_zrrc(reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) { assert(Instruction::rrrc_op_codes().count(op_code_)); assert(suffix_ == ZRRC); ra_ = ra; rb_ = rb; if (Instruction::add_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::rsub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } else if (Instruction::sub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_zrrci(reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) { assert(Instruction::rrrci_op_codes().count(op_code_)); assert(suffix_ == ZRRCI); ra_ = ra; rb_ = rb; if (Instruction::add_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ShiftNZCC(condition).condition()); } else if (Instruction::mul_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::MulNZCC(condition).condition()); } else if (Instruction::rsub_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_rri(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm) { assert(Instruction::rri_op_codes().count(op_code_)); assert(suffix_ == S_RRI or suffix_ == U_RRI); dc_ = dc; ra_ = ra; if (Instruction::add_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 32, imm); } else if (Instruction::asr_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else if (Instruction::call_rri_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 24, imm); } else { throw std::invalid_argument(""); } } void Instruction::init_s_rric(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rric_op_codes().count(op_code_)); assert(suffix_ == S_RRIC or suffix_ == U_RRIC); dc_ = dc; ra_ = ra; if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::sub_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 24, imm); } else if (Instruction::asr_rric_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rric_op_codes().count(op_code_) or Instruction::asr_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::sub_rric_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_s_rrici(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrici_op_codes().count(op_code_)); assert(suffix_ == S_RRICI or suffix_ == U_RRICI); dc_ = dc; ra_ = ra; if (Instruction::add_rrici_op_codes().count(op_code_) or Instruction::and_rrici_op_codes().count(op_code_) or Instruction::sub_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::SIGNED, 8, imm); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } else { throw std::invalid_argument(""); } if (Instruction::add_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ImmShiftNZCC(condition).condition()); } else if (Instruction::sub_rrici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_rrif(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition) { assert(Instruction::rrif_op_codes().count(op_code_)); assert(suffix_ == S_RRIF or suffix_ == U_RRIF); dc_ = dc; ra_ = ra; imm_ = new word::Immediate(word::SIGNED, 24, imm); condition_ = new isa::Condition(cc::FalseCC(condition).condition()); } void Instruction::init_s_rrr(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb) { assert(Instruction::rrr_op_codes().count(op_code_)); assert(suffix_ == S_RRR or suffix_ == U_RRR); dc_ = dc; ra_ = ra; rb_ = rb; } void Instruction::init_s_rrrc(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition) { assert(Instruction::rrrc_op_codes().count(op_code_)); assert(suffix_ == S_RRRC or suffix_ == U_RRRC); dc_ = dc; ra_ = ra; rb_ = rb; if (Instruction::add_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } else if (Instruction::rsub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } else if (Instruction::sub_rrrc_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ExtSubSetCC(condition).condition()); } else { throw std::invalid_argument(""); } } void Instruction::init_s_rrrci(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc) { assert(Instruction::rrrci_op_codes().count(op_code_)); assert(suffix_ == S_RRRCI or suffix_ == U_RRRCI); dc_ = dc; ra_ = ra; rb_ = rb; if (Instruction::add_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::AddNZCC(condition).condition()); } else if (Instruction::and_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::asr_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::ShiftNZCC(condition).condition()); } else if (Instruction::mul_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::MulNZCC(condition).condition()); } else if (Instruction::rsub_rrrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_rr(reg::GPReg *rc, reg::SrcReg *ra) { assert(Instruction::rr_op_codes().count(op_code_)); assert(suffix_ == RR); rc_ = rc; ra_ = ra; } void Instruction::init_rrc(reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rrc_op_codes().count(op_code_)); assert(suffix_ == RRC); rc_ = rc; ra_ = ra; condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } void Instruction::init_rrci(reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rrci_op_codes().count(op_code_)); assert(suffix_ == RRCI); rc_ = rc; ra_ = ra; if (Instruction::cao_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::CountNZCC(condition).condition()); } else if (Instruction::extsb_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::time_cfg_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::TrueCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_zr(reg::SrcReg *ra) { assert(Instruction::rr_op_codes().count(op_code_)); assert(suffix_ == ZR); ra_ = ra; } void Instruction::init_zrc(reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rrc_op_codes().count(op_code_)); assert(suffix_ == ZRC); ra_ = ra; condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } void Instruction::init_zrci(reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rrci_op_codes().count(op_code_)); assert(suffix_ == ZRCI); ra_ = ra; if (Instruction::cao_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::CountNZCC(condition).condition()); } else if (Instruction::extsb_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::time_cfg_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::TrueCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_rr(reg::PairReg *dc, reg::SrcReg *ra) { assert(Instruction::rr_op_codes().count(op_code_)); assert(suffix_ == S_RR or suffix_ == U_RR); dc_ = dc; ra_ = ra; } void Instruction::init_s_rrc(reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rrc_op_codes().count(op_code_)); assert(suffix_ == S_RRC or suffix_ == U_RRC); dc_ = dc; ra_ = ra; condition_ = new isa::Condition(cc::LogSetCC(condition).condition()); } void Instruction::init_s_rrci(reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rrci_op_codes().count(op_code_)); assert(suffix_ == S_RRCI or suffix_ == U_RRCI); dc_ = dc; ra_ = ra; if (Instruction::cao_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::CountNZCC(condition).condition()); } else if (Instruction::extsb_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::LogNZCC(condition).condition()); } else if (Instruction::time_cfg_rrci_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::TrueCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_drdici(reg::PairReg *dc, reg::SrcReg *ra, reg::PairReg *db, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::drdici_op_codes().count(op_code_)); assert(suffix_ == DRDICI); dc_ = dc; ra_ = ra; db_ = db; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); if (Instruction::div_step_drdici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::DivCC(condition).condition()); } else if (Instruction::mul_step_drdici_op_codes().count(op_code_)) { condition_ = new isa::Condition(cc::BootCC(condition).condition()); } else { throw std::invalid_argument(""); } pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_rrri(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) { assert(Instruction::rrri_op_codes().count(op_code_)); assert(suffix_ == RRRI); rc_ = rc; ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } void Instruction::init_rrrici(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrrici_op_codes().count(op_code_)); assert(suffix_ == RRRICI); rc_ = rc; ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); condition_ = new isa::Condition(cc::DivNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_zrri(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) { assert(Instruction::rrri_op_codes().count(op_code_)); assert(suffix_ == ZRRI); ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } void Instruction::init_zrrici(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrrici_op_codes().count(op_code_)); assert(suffix_ == ZRRICI); ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); condition_ = new isa::Condition(cc::DivNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_rrri(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) { assert(Instruction::rrri_op_codes().count(op_code_)); assert(suffix_ == S_RRRI or suffix_ == U_RRRI); dc_ = dc; ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); } void Instruction::init_s_rrrici(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc) { assert(Instruction::rrrici_op_codes().count(op_code_)); assert(suffix_ == S_RRRICI or suffix_ == U_RRRICI); dc_ = dc; ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 5, imm); condition_ = new isa::Condition(cc::DivNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_rir(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra) { assert(Instruction::rir_op_codes().count(op_code_)); assert(suffix_ == RIR); rc_ = rc; imm_ = new word::Immediate(word::UNSIGNED, 32, imm); ra_ = ra; } void Instruction::init_rirc(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rirc_op_codes().count(op_code_)); assert(suffix_ == RIRC); rc_ = rc; imm_ = new word::Immediate(word::SIGNED, 24, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } void Instruction::init_rirci(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rirci_op_codes().count(op_code_)); assert(suffix_ == RIRCI); rc_ = rc; imm_ = new word::Immediate(word::SIGNED, 8, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_zir(int64_t imm, reg::SrcReg *ra) { assert(Instruction::rir_op_codes().count(op_code_)); assert(suffix_ == ZIR); imm_ = new word::Immediate(word::UNSIGNED, 32, imm); ra_ = ra; } void Instruction::init_zirc(int64_t imm, reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rirc_op_codes().count(op_code_)); assert(suffix_ == ZIRC); imm_ = new word::Immediate(word::SIGNED, 27, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } void Instruction::init_zirci(int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rirci_op_codes().count(op_code_)); assert(suffix_ == ZIRCI); imm_ = new word::Immediate(word::SIGNED, 11, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_rirc(reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition) { assert(Instruction::rirc_op_codes().count(op_code_)); assert(suffix_ == S_RIRC or suffix_ == U_RIRC); dc_ = dc; imm_ = new word::Immediate(word::SIGNED, 24, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubSetCC(condition).condition()); } void Instruction::init_s_rirci(reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc) { assert(Instruction::rirci_op_codes().count(op_code_)); assert(suffix_ == S_RIRCI or suffix_ == U_RIRCI); dc_ = dc; imm_ = new word::Immediate(word::SIGNED, 8, imm); ra_ = ra; condition_ = new isa::Condition(cc::SubNZCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_r(reg::GPReg *rc) { assert(Instruction::r_op_codes().count(op_code_)); assert(suffix_ == R); rc_ = rc; } void Instruction::init_rci(reg::GPReg *rc, isa::Condition condition, int64_t pc) { assert(Instruction::rci_op_codes().count(op_code_)); assert(suffix_ == RCI); rc_ = rc; condition_ = new isa::Condition(cc::TrueCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_z() { assert(Instruction::r_op_codes().count(op_code_) or op_code_ == NOP); assert(suffix_ == Z); } void Instruction::init_zci(isa::Condition condition, int64_t pc) { assert(Instruction::rci_op_codes().count(op_code_)); assert(suffix_ == ZCI); condition_ = new isa::Condition(cc::TrueCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_s_r(reg::PairReg *dc) { assert(Instruction::r_op_codes().count(op_code_)); assert(suffix_ == S_R or suffix_ == U_R); dc_ = dc; } void Instruction::init_s_rci(reg::PairReg *dc, isa::Condition condition, int64_t pc) { assert(Instruction::rci_op_codes().count(op_code_)); assert(suffix_ == S_RCI or suffix_ == U_RCI); dc_ = dc; condition_ = new isa::Condition(cc::TrueCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_ci(isa::Condition condition, int64_t pc) { assert(Instruction::ci_op_codes().count(op_code_)); assert(suffix_ == CI); condition_ = new isa::Condition(cc::BootCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_i(int64_t imm) { assert(Instruction::i_op_codes().count(op_code_)); assert(suffix_ == I); imm_ = new word::Immediate(word::SIGNED, 24, imm); } void Instruction::init_ddci(reg::PairReg *dc, reg::PairReg *db, isa::Condition condition, int64_t pc) { assert(Instruction::ddci_op_codes().count(op_code_)); assert(suffix_ == DDCI); dc_ = dc; db_ = db; condition_ = new isa::Condition(cc::TrueFalseCC(condition).condition()); pc_ = new word::Immediate(word::UNSIGNED, util::ConfigLoader::iram_address_width(), pc); } void Instruction::init_erri(isa::Endian endian, reg::GPReg *rc, reg::SrcReg *ra, int64_t off) { assert(Instruction::erri_op_codes().count(op_code_)); assert(suffix_ == ERRI); endian_ = new isa::Endian(endian); rc_ = rc; ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); } void Instruction::init_s_erri(isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off) { assert(Instruction::erri_op_codes().count(op_code_)); assert(suffix_ == S_ERRI or suffix_ == U_ERRI); endian_ = new isa::Endian(endian); dc_ = dc; ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); } void Instruction::init_edri(isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off) { assert(Instruction::edri_op_codes().count(op_code_)); assert(suffix_ == EDRI); endian_ = new isa::Endian(endian); dc_ = dc; ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); } void Instruction::init_erii(isa::Endian endian, reg::SrcReg *ra, int64_t off, int64_t imm) { assert(Instruction::erii_op_codes().count(op_code_)); assert(suffix_ == ERII); endian_ = new isa::Endian(endian); ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); imm_ = new word::Immediate(word::SIGNED, 16, imm); } void Instruction::init_erir(isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::SrcReg *rb) { assert(Instruction::erir_op_codes().count(op_code_)); assert(suffix_ == ERIR); endian_ = new isa::Endian(endian); ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); rb_ = rb; } void Instruction::init_erid(isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::PairReg *db) { assert(Instruction::erid_op_codes().count(op_code_)); assert(suffix_ == ERID); endian_ = new isa::Endian(endian); ra_ = ra; off_ = new word::Immediate(word::SIGNED, 24, off); db_ = db; } void Instruction::init_dma_rri(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm) { assert(Instruction::dma_rri_op_codes().count(op_code_)); assert(suffix_ == DMA_RRI); ra_ = ra; rb_ = rb; imm_ = new word::Immediate(word::UNSIGNED, 8, imm); } } // namespace upmem_sim::abi::instruction ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/instruction/instruction.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_INSTRUCTION_INSTRUCTION_H_ #define UPMEM_SIM_ABI_ISA_INSTRUCTION_INSTRUCTION_H_ #include #include "abi/instruction/op_code.h" #include "abi/instruction/suffix.h" #include "abi/isa/condition.h" #include "abi/isa/endian.h" #include "abi/reg/pair_reg.h" #include "abi/reg/src_reg.h" #include "abi/word/immediate.h" #include "simulator/dpu/thread.h" namespace upmem_sim::abi::instruction { class Instruction { public: static std::set acquire_rici_op_codes() { return {ACQUIRE}; } static std::set release_rici_op_codes() { return {RELEASE}; } static std::set boot_rici_op_codes() { return {BOOT, RESUME}; } static std::set rici_op_codes() { std::set acquire_rici_op_codes = Instruction::acquire_rici_op_codes(); std::set release_rici_op_codes = Instruction::release_rici_op_codes(); std::set boot_rici_op_codes = Instruction::boot_rici_op_codes(); std::set rici_op_codes = {}; rici_op_codes.insert(acquire_rici_op_codes.begin(), acquire_rici_op_codes.end()); rici_op_codes.insert(release_rici_op_codes.begin(), release_rici_op_codes.end()); rici_op_codes.insert(boot_rici_op_codes.begin(), boot_rici_op_codes.end()); return rici_op_codes; } static std::set add_rri_op_codes() { return {ADD, ADDC, AND, OR, XOR}; } static std::set asr_rri_op_codes() { return {ASR, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, ROL, ROR}; } static std::set call_rri_op_codes() { return {CALL}; } static std::set rri_op_codes() { std::set add_rri_op_codes = Instruction::add_rri_op_codes(); std::set asr_rri_op_codes = Instruction::asr_rri_op_codes(); std::set call_rri_op_codes = Instruction::call_rri_op_codes(); std::set rri_op_codes = {}; rri_op_codes.insert(add_rri_op_codes.begin(), add_rri_op_codes.end()); rri_op_codes.insert(asr_rri_op_codes.begin(), asr_rri_op_codes.end()); rri_op_codes.insert(call_rri_op_codes.begin(), call_rri_op_codes.end()); return rri_op_codes; } static std::set add_rric_op_codes() { return {ADD, ADDC, AND, ANDN, NAND, NOR, NXOR, OR, ORN, XOR, HASH}; } static std::set asr_rric_op_codes() { return {ASR, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, ROL, ROR}; } static std::set sub_rric_op_codes() { return {SUB, SUBC}; } static std::set rric_op_codes() { std::set add_rric_op_codes = Instruction::add_rric_op_codes(); std::set asr_rric_op_codes = Instruction::asr_rric_op_codes(); std::set sub_rric_op_codes = Instruction::sub_rric_op_codes(); std::set rric_op_codes = {}; rric_op_codes.insert(add_rric_op_codes.begin(), add_rric_op_codes.end()); rric_op_codes.insert(asr_rric_op_codes.begin(), asr_rric_op_codes.end()); rric_op_codes.insert(sub_rric_op_codes.begin(), sub_rric_op_codes.end()); return rric_op_codes; } static std::set add_rrici_op_codes() { return {ADD, ADDC}; } static std::set and_rrici_op_codes() { return {AND, ANDN, NAND, NOR, NXOR, OR, ORN, XOR, HASH}; } static std::set asr_rrici_op_codes() { return {ASR, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, ROL, ROR}; } static std::set sub_rrici_op_codes() { return {SUB, SUBC}; } static std::set rrici_op_codes() { std::set add_rrici_op_codes = Instruction::add_rrici_op_codes(); std::set and_rrici_op_codes = Instruction::and_rrici_op_codes(); std::set asr_rrici_op_codes = Instruction::asr_rrici_op_codes(); std::set sub_rrici_op_codes = Instruction::sub_rrici_op_codes(); std::set rrici_op_codes = {}; rrici_op_codes.insert(add_rrici_op_codes.begin(), add_rrici_op_codes.end()); rrici_op_codes.insert(and_rrici_op_codes.begin(), and_rrici_op_codes.end()); rrici_op_codes.insert(asr_rrici_op_codes.begin(), asr_rrici_op_codes.end()); rrici_op_codes.insert(sub_rrici_op_codes.begin(), sub_rrici_op_codes.end()); return rrici_op_codes; } static std::set rrif_op_codes() { return {ADD, ADDC, AND, ANDN, NAND, NOR, NXOR, OR, ORN, SUB, SUBC, XOR, HASH}; } static std::set rrr_op_codes() { return {ADD, ADDC, AND, ANDN, ASR, CMPB4, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, MUL_SH_SH, MUL_SH_SL, MUL_SH_UH, MUL_SH_UL, MUL_SL_SH, MUL_SL_SL, MUL_SL_UH, MUL_SL_UL, MUL_UH_UH, MUL_UH_UL, MUL_UL_UH, MUL_UL_UL, NAND, NOR, NXOR, OR, ORN, ROL, ROR, RSUB, RSUBC, SUB, SUBC, XOR, HASH, CALL}; } static std::set add_rrrc_op_codes() { return {ADD, ADDC, AND, ANDN, ASR, CMPB4, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, MUL_SH_SH, MUL_SH_SL, MUL_SH_UH, MUL_SH_UL, MUL_SL_SH, MUL_SL_SL, MUL_SL_UH, MUL_SL_UL, MUL_UH_UH, MUL_UH_UL, MUL_UL_UH, MUL_UL_UL, NAND, NOR, NXOR, ROL, ROR, OR, ORN, XOR, HASH, CALL}; } static std::set rsub_rrrc_op_codes() { return {RSUB, RSUBC}; } static std::set sub_rrrc_op_codes() { return {SUB, SUBC}; } static std::set rrrc_op_codes() { std::set add_rrrc_op_codes = Instruction::add_rrrc_op_codes(); std::set rsub_rrrc_op_codes = Instruction::rsub_rrrc_op_codes(); std::set sub_rrrc_op_codes = Instruction::sub_rrrc_op_codes(); std::set rrrc_op_codes = {}; rrrc_op_codes.insert(add_rrrc_op_codes.begin(), add_rrrc_op_codes.end()); rrrc_op_codes.insert(rsub_rrrc_op_codes.begin(), rsub_rrrc_op_codes.end()); rrrc_op_codes.insert(sub_rrrc_op_codes.begin(), sub_rrrc_op_codes.end()); return rrrc_op_codes; } static std::set add_rrrci_op_codes() { return {ADD, ADDC}; } static std::set and_rrrci_op_codes() { return {AND, ANDN, NAND, NOR, NXOR, OR, ORN, XOR, HASH}; } static std::set asr_rrrci_op_codes() { return {ASR, CMPB4, LSL, LSL1, LSL1X, LSLX, LSR, LSR1, LSR1X, LSRX, ROL, ROR}; } static std::set mul_rrrci_op_codes() { return {MUL_SH_SH, MUL_SH_SL, MUL_SH_UH, MUL_SH_UL, MUL_SL_SH, MUL_SL_SL, MUL_SL_UH, MUL_SL_UL, MUL_UH_UH, MUL_UH_UL, MUL_UL_UH, MUL_UL_UL}; } static std::set rsub_rrrci_op_codes() { return {RSUB, RSUBC, SUB, SUBC}; } static std::set rrrci_op_codes() { std::set add_rrrci_op_codes = Instruction::add_rrrci_op_codes(); std::set and_rrrci_op_codes = Instruction::and_rrrci_op_codes(); std::set asr_rrrci_op_codes = Instruction::asr_rrici_op_codes(); std::set mul_rrrci_op_codes = Instruction::mul_rrrci_op_codes(); std::set rsub_rrrci_op_codes = Instruction::rsub_rrrci_op_codes(); std::set rrrci_op_codes = {}; rrrci_op_codes.insert(add_rrrci_op_codes.begin(), add_rrrci_op_codes.end()); rrrci_op_codes.insert(and_rrrci_op_codes.begin(), and_rrrci_op_codes.end()); rrrci_op_codes.insert(asr_rrrci_op_codes.begin(), asr_rrrci_op_codes.end()); rrrci_op_codes.insert(mul_rrrci_op_codes.begin(), mul_rrrci_op_codes.end()); rrrci_op_codes.insert(rsub_rrrci_op_codes.begin(), rsub_rrrci_op_codes.end()); return rrrci_op_codes; } static std::set rr_op_codes() { return {CAO, CLO, CLS, CLZ, EXTSB, EXTSH, EXTUB, EXTUH, SATS, TIME_CFG}; } static std::set rrc_op_codes() { return {CAO, CLO, CLS, CLZ, EXTSB, EXTSH, EXTUB, EXTUH, SATS}; } static std::set cao_rrci_op_codes() { return {CAO, CLO, CLS, CLZ}; } static std::set extsb_rrci_op_codes() { return {EXTSB, EXTSH, EXTUB, EXTUH, SATS}; } static std::set time_cfg_rrci_op_codes() { return {TIME_CFG}; } static std::set rrci_op_codes() { std::set cao_rrci_op_codes = Instruction::cao_rrci_op_codes(); std::set extsb_rrci_op_codes = Instruction::extsb_rrci_op_codes(); std::set time_cfg_rrci_op_codes = Instruction::time_cfg_rrci_op_codes(); std::set rrci_op_codes = {}; rrci_op_codes.insert(cao_rrci_op_codes.begin(), cao_rrci_op_codes.end()); rrci_op_codes.insert(extsb_rrci_op_codes.begin(), extsb_rrci_op_codes.end()); rrci_op_codes.insert(time_cfg_rrci_op_codes.begin(), time_cfg_rrci_op_codes.end()); return rrci_op_codes; } static std::set div_step_drdici_op_codes() { return {DIV_STEP}; } static std::set mul_step_drdici_op_codes() { return {MUL_STEP}; } static std::set drdici_op_codes() { std::set div_step_drdici_op_codes = Instruction::div_step_drdici_op_codes(); std::set mul_step_drdici_op_codes = Instruction::mul_step_drdici_op_codes(); std::set drdici_op_codes = {}; drdici_op_codes.insert(div_step_drdici_op_codes.begin(), div_step_drdici_op_codes.end()); drdici_op_codes.insert(mul_step_drdici_op_codes.begin(), mul_step_drdici_op_codes.end()); return drdici_op_codes; } static std::set rrri_op_codes() { return {LSL_ADD, LSL_SUB, LSR_ADD, ROL_ADD}; } static std::set rrrici_op_codes() { return {LSL_ADD, LSL_SUB, LSR_ADD, ROL_ADD}; } static std::set rir_op_codes() { return {SUB, SUBC}; } static std::set rirc_op_codes() { return {SUB, SUBC}; } static std::set rirci_op_codes() { return {SUB, SUBC}; } static std::set r_op_codes() { return {TIME}; } static std::set rci_op_codes() { return {TIME}; } static std::set ci_op_codes() { return {STOP}; } static std::set i_op_codes() { return {FAULT}; } static std::set movd_ddci_op_codes() { return {MOVD}; } static std::set swapd_ddci_op_codes() { return {SWAPD}; } static std::set ddci_op_codes() { std::set movd_ddci_op_codes = Instruction::movd_ddci_op_codes(); std::set swapd_ddci_op_codes = Instruction::swapd_ddci_op_codes(); std::set ddci_op_codes = {}; ddci_op_codes.insert(movd_ddci_op_codes.begin(), movd_ddci_op_codes.end()); ddci_op_codes.insert(swapd_ddci_op_codes.begin(), swapd_ddci_op_codes.end()); return ddci_op_codes; } static std::set erri_op_codes() { return {LBS, LBU, LHS, LHU, LW}; } static std::set edri_op_codes() { return {LD}; } static std::set erii_op_codes() { return {SB, SB_ID, SD, SD_ID, SH, SH_ID, SW, SW_ID, SD, SD_ID}; } static std::set erir_op_codes() { return {SB, SH, SW}; } static std::set erid_op_codes() { return {SD}; } static std::set ldma_dma_rri_op_codes() { return {LDMA}; } static std::set ldmai_dma_rri_op_codes() { return {LDMAI}; } static std::set sdma_dma_rri_op_codes() { return {SDMA}; } static std::set dma_rri_op_codes() { std::set ldma_dma_rri_op_codes = Instruction::ldma_dma_rri_op_codes(); std::set ldmai_dma_rri_op_codes = Instruction::ldmai_dma_rri_op_codes(); std::set sdma_dma_rri_op_codes = Instruction::sdma_dma_rri_op_codes(); std::set dma_rri_op_codes = {}; dma_rri_op_codes.insert(ldma_dma_rri_op_codes.begin(), ldma_dma_rri_op_codes.end()); dma_rri_op_codes.insert(ldmai_dma_rri_op_codes.begin(), ldmai_dma_rri_op_codes.end()); dma_rri_op_codes.insert(sdma_dma_rri_op_codes.begin(), sdma_dma_rri_op_codes.end()); return dma_rri_op_codes; } explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, int64_t imm, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::PairReg *db, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra); explicit Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc); explicit Instruction(OpCode op_code, Suffix suffix, reg::GPReg *rc, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix); explicit Instruction(OpCode op_code, Suffix suffix, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, reg::PairReg *dc, reg::PairReg *db, isa::Condition condition, int64_t pc); explicit Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::GPReg *rc, reg::SrcReg *ra, int64_t off); explicit Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off); explicit Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, int64_t imm); explicit Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::SrcReg *rb); explicit Instruction(OpCode op_code, Suffix suffix, isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::PairReg *db); ~Instruction(); OpCode op_code() { return op_code_; } Suffix suffix() { return suffix_; } reg::GPReg *rc(); reg::SrcReg *ra(); reg::SrcReg *rb(); reg::PairReg *dc(); reg::PairReg *db(); isa::Condition condition(); abi::word::Immediate *imm(); abi::word::Immediate *off(); abi::word::Immediate *pc(); isa::Endian endian(); simulator::dpu::Thread *thread(); void set_thread(simulator::dpu::Thread *thread); protected: void init_rici(reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); void init_rri(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm); void init_rric(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_rrici(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); void init_rrif(reg::GPReg *rc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_rrr(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb); void init_rrrc(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); void init_rrrci(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); void init_zri(reg::SrcReg *ra, int64_t imm); void init_zric(reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_zrici(reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); void init_zrif(reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_zrr(reg::SrcReg *ra, reg::SrcReg *rb); void init_zrrc(reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); void init_zrrci(reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); void init_s_rri(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm); void init_s_rric(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_s_rrici(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition, int64_t pc); void init_s_rrif(reg::PairReg *dc, reg::SrcReg *ra, int64_t imm, isa::Condition condition); void init_s_rrr(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb); void init_s_rrrc(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition); void init_s_rrrci(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, isa::Condition condition, int64_t pc); void init_rr(reg::GPReg *rc, reg::SrcReg *ra); void init_rrc(reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition); void init_rrci(reg::GPReg *rc, reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_zr(reg::SrcReg *ra); void init_zrc(reg::SrcReg *ra, isa::Condition condition); void init_zrci(reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_s_rr(reg::PairReg *dc, reg::SrcReg *ra); void init_s_rrc(reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition); void init_s_rrci(reg::PairReg *dc, reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_drdici(reg::PairReg *dc, reg::SrcReg *ra, reg::PairReg *db, int64_t imm, isa::Condition condition, int64_t pc); void init_rrri(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); void init_rrrici(reg::GPReg *rc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); void init_zrri(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); void init_zrrici(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); void init_s_rrri(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); void init_s_rrrici(reg::PairReg *dc, reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm, isa::Condition condition, int64_t pc); void init_rir(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra); void init_rirc(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition); void init_rirci(reg::GPReg *rc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_zir(int64_t imm, reg::SrcReg *ra); void init_zirc(int64_t imm, reg::SrcReg *ra, isa::Condition condition); void init_zirci(int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_s_rirc(reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition); void init_s_rirci(reg::PairReg *dc, int64_t imm, reg::SrcReg *ra, isa::Condition condition, int64_t pc); void init_r(reg::GPReg *rc); void init_rci(reg::GPReg *rc, isa::Condition condition, int64_t pc); void init_z(); void init_zci(isa::Condition condition, int64_t pc); void init_s_r(reg::PairReg *dc); void init_s_rci(reg::PairReg *dc, isa::Condition condition, int64_t pc); void init_ci(isa::Condition condition, int64_t pc); void init_i(int64_t imm); void init_ddci(reg::PairReg *dc, reg::PairReg *db, isa::Condition condition, int64_t pc); void init_erri(isa::Endian endian, reg::GPReg *rc, reg::SrcReg *ra, int64_t off); void init_s_erri(isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off); void init_edri(isa::Endian endian, reg::PairReg *dc, reg::SrcReg *ra, int64_t off); void init_erii(isa::Endian endian, reg::SrcReg *ra, int64_t off, int64_t imm); void init_erir(isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::SrcReg *rb); void init_erid(isa::Endian endian, reg::SrcReg *ra, int64_t off, reg::PairReg *db); void init_dma_rri(reg::SrcReg *ra, reg::SrcReg *rb, int64_t imm); private: OpCode op_code_; Suffix suffix_; reg::GPReg *rc_; reg::SrcReg *ra_; reg::SrcReg *rb_; reg::PairReg *dc_; reg::PairReg *db_; isa::Condition *condition_; abi::word::Immediate *imm_; abi::word::Immediate *off_; abi::word::Immediate *pc_; isa::Endian *endian_; simulator::dpu::Thread *thread_; }; } // namespace upmem_sim::abi::instruction #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/instruction/op_code.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_INSTRUCTION_OP_CODE_H_ #define UPMEM_SIM_ABI_ISA_INSTRUCTION_OP_CODE_H_ namespace upmem_sim::abi::instruction { enum OpCode { ACQUIRE, RELEASE, ADD, ADDC, AND, ANDN, ASR, CAO, CLO, CLS, CLZ, CMPB4, DIV_STEP, EXTSB, EXTSH, EXTUB, EXTUH, LSL, LSL_ADD, LSL_SUB, LSL1, LSL1X, LSLX, LSR, LSR_ADD, LSR1, LSR1X, LSRX, MUL_SH_SH, MUL_SH_SL, MUL_SH_UH, MUL_SH_UL, MUL_SL_SH, MUL_SL_SL, MUL_SL_UH, MUL_SL_UL, MUL_STEP, MUL_UH_UH, MUL_UH_UL, MUL_UL_UH, MUL_UL_UL, NAND, NOR, NXOR, OR, ORN, ROL, ROL_ADD, ROR, RSUB, RSUBC, SUB, SUBC, XOR, BOOT, RESUME, STOP, CALL, FAULT, NOP, SATS, MOVD, SWAPD, HASH, TIME, TIME_CFG, LBS, LBU, LD, LHS, LHU, LW, SB, SB_ID, SD, SD_ID, SH, SH_ID, SW, SW_ID, LDMA, LDMAI, SDMA }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/instruction/suffix.h ================================================ #ifndef UPMEM_SIM_ISA_SUFFIX_H_ #define UPMEM_SIM_ISA_SUFFIX_H_ namespace upmem_sim::abi::instruction { enum Suffix { RICI, RRI, RRIC, RRICI, RRIF, RRR, RRRC, RRRCI, ZRI, ZRIC, ZRICI, ZRIF, ZRR, ZRRC, ZRRCI, S_RRI, S_RRIC, S_RRICI, S_RRIF, S_RRR, S_RRRC, S_RRRCI, U_RRI, U_RRIC, U_RRICI, U_RRIF, U_RRR, U_RRRC, U_RRRCI, RR, RRC, RRCI, ZR, ZRC, ZRCI, S_RR, S_RRC, S_RRCI, U_RR, U_RRC, U_RRCI, DRDICI, RRRI, RRRICI, ZRRI, ZRRICI, S_RRRI, S_RRRICI, U_RRRI, U_RRRICI, RIR, RIRC, RIRCI, ZIR, ZIRC, ZIRCI, S_RIRC, S_RIRCI, U_RIRC, U_RIRCI, R, RCI, Z, ZCI, S_R, S_RCI, U_R, U_RCI, CI, I, DDCI, ERRI, S_ERRI, U_ERRI, EDRI, ERII, ERIR, ERID, DMA_RRI }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/isa/condition.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_INSTRUCTION_CONDITION_H_ #define UPMEM_SIM_ABI_ISA_INSTRUCTION_CONDITION_H_ namespace upmem_sim::abi::isa { enum Condition { TRUE, FALSE, Z, NZ, E, O, PL, MI, OV, NOV, C, NC, SZ, SNZ, SPL, SMI, SO, SE, NC5, NC6, NC7, NC8, NC9, NC10, NC11, NC12, NC13, NC14, MAX, NMAX, SH32, NSH32, EQ, NEQ, LTU, LEU, GTU, GEU, LTS, LES, GTS, GES, XZ, XNZ, XLEU, XGTU, XLES, XGTS, SMALL, LARGE }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/isa/endian.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_INSTRUCTION_ENDIAN_H_ #define UPMEM_SIM_ABI_ISA_INSTRUCTION_ENDIAN_H_ namespace upmem_sim::abi::isa { enum Endian { LITTLE, BIG }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/isa/exception.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_EXCEPTION_H_ #define UPMEM_SIM_ABI_ISA_EXCEPTION_H_ namespace upmem_sim::abi::isa { enum Exception { MEMORY_FAULT, DMA_FAULT, HEAP_FULL, DIVISION_BY_ZERO, ASSERT, HALT, PRINT_OVERFLOW, ALREADY_PROFILING, NOT_PROFILING }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/isa/flag.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_FLAG_H_ #define UPMEM_SIM_ABI_ISA_FLAG_H_ namespace upmem_sim::abi::isa { enum Flag { ZERO, CARRY }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/gp_reg.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_REG_GP_REG_H_ #define UPMEM_SIM_ABI_ISA_REG_GP_REG_H_ #include #include #include "util/config_loader.h" namespace upmem_sim::abi::reg { class GPReg { public: explicit GPReg(RegIndex index) : index_(index) { assert(0 <= index and index < util::ConfigLoader::num_gp_registers()); } ~GPReg() = default; RegIndex index() { return index_; } private: RegIndex index_; }; } // namespace upmem_sim::abi::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/pair_reg.cc ================================================ #include "pair_reg.h" #include namespace upmem_sim::abi::reg { PairReg::PairReg(RegIndex index) { assert(index % 2 == 0); even_reg_ = new GPReg(index); odd_reg_ = new GPReg(index + 1); } PairReg::~PairReg() { delete even_reg_; delete odd_reg_; } } // namespace upmem_sim::abi::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/pair_reg.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_REG_PAIR_REG_H_ #define UPMEM_SIM_ABI_ISA_REG_PAIR_REG_H_ #include #include "gp_reg.h" namespace upmem_sim::abi::reg { class PairReg { public: explicit PairReg(RegIndex index); ~PairReg(); GPReg *even_reg() { return even_reg_; } GPReg *odd_reg() { return odd_reg_; } private: GPReg *even_reg_; GPReg *odd_reg_; }; } // namespace upmem_sim::abi::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/sp_reg.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_REG_SP_REG_H_ #define UPMEM_SIM_ABI_ISA_REG_SP_REG_H_ namespace upmem_sim::abi::reg { enum SPReg { ZERO, ONE, LNEG, MNEG, ID, ID2, ID4, ID8 }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/src_reg.cc ================================================ #include "src_reg.h" #include namespace upmem_sim::abi::reg { SrcReg::~SrcReg() { delete gp_reg_; delete sp_reg_; } GPReg *SrcReg::gp_reg() { assert(is_gp_reg()); return gp_reg_; } SPReg *SrcReg::sp_reg() { assert(is_sp_reg()); return sp_reg_; } } // namespace upmem_sim::abi::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/reg/src_reg.h ================================================ #ifndef UPMEM_SIM_ABI_ISA_REG_SRC_REG_H_ #define UPMEM_SIM_ABI_ISA_REG_SRC_REG_H_ #include "gp_reg.h" #include "sp_reg.h" namespace upmem_sim::abi::reg { class SrcReg { public: explicit SrcReg(GPReg *reg) : gp_reg_(new GPReg(reg->index())), sp_reg_(nullptr) {} explicit SrcReg(SPReg *reg) : gp_reg_(nullptr), sp_reg_(new SPReg(*reg)) {} ~SrcReg(); bool is_gp_reg() { return gp_reg_ != nullptr; } bool is_sp_reg() { return sp_reg_ != nullptr; } GPReg *gp_reg(); SPReg *sp_reg(); private: GPReg *gp_reg_; SPReg *sp_reg_; }; } // namespace upmem_sim::abi::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/_base_word.cc ================================================ #include "abi/word/_base_word.h" #include #include #include namespace upmem_sim::abi::word { _BaseWord::_BaseWord(int width) { assert(width > 0); bits_.resize(width); } int64_t _BaseWord::bit_slice(Representation representation, int begin, int end) { assert(0 <= begin and begin < end and end <= width()); assert(end - begin < 64); int slice_width = end - begin; int64_t value = 0; for (int i = 0; i < slice_width; i++) { if (bit(begin + i)) { if (representation == SIGNED and i == slice_width - 1) { value -= static_cast(pow(2, i)); } else { value += static_cast(pow(2, i)); } } } return value; } void _BaseWord::set_bit_slice(int begin, int end, int64_t value) { assert(0 <= begin and begin < end and end <= width()); assert(end - begin < 64); if (value >= 0) { set_positive_bit_slice(begin, end, value); } else { set_negative_bit_slice(begin, end, value); } } encoder::ByteStream *_BaseWord::to_byte_stream() { int num_bytes = ceil(width() / 8.0); auto byte_stream = new encoder::ByteStream(); for (int i = 0; i < num_bytes; i++) { int begin = 8 * i; int end = std::min(begin + 8, width()); auto byte = static_cast(bit_slice(UNSIGNED, begin, end)); byte_stream->append(byte); } return byte_stream; } void _BaseWord::from_byte_stream(encoder::ByteStream *byte_stream) { for (int i = 0; i < byte_stream->size(); i++) { int begin = 8 * i; int end = std::min(begin + 8, width()); int64_t byte = byte_stream->byte(i); set_bit_slice(begin, end, byte); } } void _BaseWord::set_positive_bit_slice(int begin, int end, int64_t value) { assert(0 <= begin and begin < end and end <= width()); assert(value >= 0); int slice_width = end - begin; for (int i = 0; i < slice_width; i++) { if (value % 2) { set_bit(begin + i); } else { clear_bit(begin + i); } value /= 2; } assert(value == 0); } void _BaseWord::set_negative_bit_slice(int begin, int end, int64_t value) { assert(0 <= begin and begin < end and end <= width()); assert(value < 0); set_bit(end - 1); if (begin + 1 < end) { int slice_width = end - begin; value += static_cast(pow(2, slice_width - 1)); set_positive_bit_slice(begin, end - 1, value); } } } // namespace upmem_sim::abi::word ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/_base_word.h ================================================ #ifndef UPMEM_SIM_ABI_WORD__BASE_WORD_H_ #define UPMEM_SIM_ABI_WORD__BASE_WORD_H_ #include #include #include "abi/word/representation.h" #include "encoder/byte_stream.h" #include "main.h" namespace upmem_sim::abi::word { class _BaseWord { public: explicit _BaseWord(int width); ~_BaseWord() = default; int width() { return static_cast(bits_.size()); } Address size() { return width() / 8; } bool sign_bit() { return bit(width() - 1); } bool bit(int index) { return bits_[index]; } void set_bit(int index) { bits_[index] = true; } void clear_bit(int index) { bits_[index] = false; } int64_t bit_slice(Representation representation, int begin, int end); void set_bit_slice(int begin, int end, int64_t value); int64_t value(Representation representation) { return bit_slice(representation, 0, width()); } void set_value(int64_t value) { set_bit_slice(0, width(), value); } encoder::ByteStream *to_byte_stream(); void from_byte_stream(encoder::ByteStream *byte_stream); protected: void set_positive_bit_slice(int begin, int end, int64_t value); void set_negative_bit_slice(int begin, int end, int64_t value); private: std::vector bits_; }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/data_address_word.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_DATA_ADDRESS_WORD_H_ #define UPMEM_SIM_ABI_WORD_DATA_ADDRESS_WORD_H_ #include "abi/word/_base_word.h" #include "util/config_loader.h" namespace upmem_sim::abi::word { class DataAddressWord : public _BaseWord { public: DataAddressWord() : _BaseWord(util::ConfigLoader::mram_address_width()) { assert(util::ConfigLoader::atomic_address_width() == util::ConfigLoader::wram_address_width() and util::ConfigLoader::atomic_address_width() == util::ConfigLoader::mram_address_width()); } ~DataAddressWord() = default; Address address() { return value(UNSIGNED); } }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/data_word.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_DATA_WORD_H_ #define UPMEM_SIM_ABI_WORD_DATA_WORD_H_ #include "abi/word/_base_word.h" #include "util/config_loader.h" namespace upmem_sim::abi::word { class DataWord : public _BaseWord { public: DataWord() : _BaseWord(util::ConfigLoader::mram_data_width()) { assert(util::ConfigLoader::atomic_data_width() == util::ConfigLoader::wram_data_width() and util::ConfigLoader::atomic_data_width() == util::ConfigLoader::mram_data_width()); } ~DataWord() = default; }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/immediate.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_IMMEDIATE_H_ #define UPMEM_SIM_ABI_WORD_IMMEDIATE_H_ #include #include "abi/word/_base_word.h" #include "abi/word/representation.h" #include "encoder/byte_stream.h" namespace upmem_sim::abi::word { class Immediate { public: Immediate(Representation representation, int width, int64_t value) : representation_(representation), word_(new _BaseWord(width)) { word_->set_value(value); } ~Immediate() { delete word_; } Representation representation() { return representation_; } int width() { return word_->width(); } bool bit(int index) { return word_->bit(index); } int64_t bit_slice(int begin, int end) { return word_->bit_slice(representation_, begin, end); } int64_t value() { return word_->value(representation_); } encoder::ByteStream *to_byte_stream() { return word_->to_byte_stream(); } private: Representation representation_; _BaseWord *word_; }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/instruction_address_word.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_INSTRUCTION_ADDRESS_WORD_H_ #define UPMEM_SIM_ABI_WORD_INSTRUCTION_ADDRESS_WORD_H_ #include "abi/word/_base_word.h" #include "util/config_loader.h" namespace upmem_sim::abi::word { class InstructionAddressWord : public _BaseWord { public: InstructionAddressWord() : _BaseWord(util::ConfigLoader::iram_address_width()) {} ~InstructionAddressWord() = default; Address address() { return value(UNSIGNED); } }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/instruction_word.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_INSTRUCTION_WORD_H_ #define UPMEM_SIM_ABI_WORD_INSTRUCTION_WORD_H_ #include "abi/word/_base_word.h" #include "util/config_loader.h" namespace upmem_sim::abi::word { class InstructionWord : public _BaseWord { public: InstructionWord() : _BaseWord(util::ConfigLoader::iram_data_width()) {} ~InstructionWord() = default; }; } // namespace upmem_sim::abi::word #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/abi/word/representation.h ================================================ #ifndef UPMEM_SIM_ABI_WORD_REPRESENTATION_H_ #define UPMEM_SIM_ABI_WORD_REPRESENTATION_H_ namespace upmem_sim::abi::word { enum Representation { UNSIGNED, SIGNED }; } #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/condition_converter.cc ================================================ #include "converter/condition_converter.h" #include namespace upmem_sim::converter { std::string ConditionConverter::to_string(abi::isa::Condition condition) { if (condition == abi::isa::TRUE) { return "true"; } else if (condition == abi::isa::FALSE) { return "false"; } else if (condition == abi::isa::Z) { return "z"; } else if (condition == abi::isa::NZ) { return "nz"; } else if (condition == abi::isa::E) { return "e"; } else if (condition == abi::isa::O) { return "o"; } else if (condition == abi::isa::PL) { return "pl"; } else if (condition == abi::isa::MI) { return "mi"; } else if (condition == abi::isa::OV) { return "ov"; } else if (condition == abi::isa::NOV) { return "nov"; } else if (condition == abi::isa::C) { return "c"; } else if (condition == abi::isa::NC) { return "nc"; } else if (condition == abi::isa::SZ) { return "sz"; } else if (condition == abi::isa::SNZ) { return "snz"; } else if (condition == abi::isa::SPL) { return "spl"; } else if (condition == abi::isa::SMI) { return "smi"; } else if (condition == abi::isa::SO) { return "so"; } else if (condition == abi::isa::SE) { return "se"; } else if (condition == abi::isa::NC5) { return "nc5"; } else if (condition == abi::isa::NC6) { return "nc6"; } else if (condition == abi::isa::NC7) { return "nc7"; } else if (condition == abi::isa::NC8) { return "nc8"; } else if (condition == abi::isa::NC9) { return "nc9"; } else if (condition == abi::isa::NC10) { return "nc10"; } else if (condition == abi::isa::NC11) { return "nc11"; } else if (condition == abi::isa::NC12) { return "nc12"; } else if (condition == abi::isa::NC13) { return "nc13"; } else if (condition == abi::isa::NC14) { return "nc14"; } else if (condition == abi::isa::MAX) { return "max"; } else if (condition == abi::isa::NMAX) { return "nmax"; } else if (condition == abi::isa::SH32) { return "sh32"; } else if (condition == abi::isa::NSH32) { return "nsh32"; } else if (condition == abi::isa::EQ) { return "eq"; } else if (condition == abi::isa::NEQ) { return "neq"; } else if (condition == abi::isa::LTU) { return "ltu"; } else if (condition == abi::isa::LEU) { return "leu"; } else if (condition == abi::isa::GTU) { return "gtu"; } else if (condition == abi::isa::GEU) { return "geu"; } else if (condition == abi::isa::LTS) { return "lts"; } else if (condition == abi::isa::LES) { return "les"; } else if (condition == abi::isa::GTS) { return "gts"; } else if (condition == abi::isa::GES) { return "ges"; } else if (condition == abi::isa::XZ) { return "xz"; } else if (condition == abi::isa::XNZ) { return "xnz"; } else if (condition == abi::isa::XLEU) { return "xleu"; } else if (condition == abi::isa::XGTU) { return "xgtu"; } else if (condition == abi::isa::XLES) { return "xles"; } else if (condition == abi::isa::XGTS) { return "xgts"; } else if (condition == abi::isa::SMALL) { return "small"; } else if (condition == abi::isa::LARGE) { return "large"; } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/condition_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_CONDITION_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_CONDITION_CONVERTER_H_ #include #include "abi/isa/condition.h" namespace upmem_sim::converter { class ConditionConverter { public: static std::string to_string(abi::isa::Condition condition); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/endian_converter.cc ================================================ #include "converter/endian_converter.h" #include namespace upmem_sim::converter { std::string EndianConverter::to_string(abi::isa::Endian endian) { if (endian == abi::isa::LITTLE) { return "!little"; } else if (endian == abi::isa::BIG) { return "!big"; } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/endian_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_ENDIAN_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_ENDIAN_CONVERTER_H_ #include #include "abi/isa/endian.h" namespace upmem_sim::converter { class EndianConverter { public: static std::string to_string(abi::isa::Endian endian); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/flag_converter.cc ================================================ #include "converter/flag_converter.h" #include namespace upmem_sim::converter { std::string FlagConverter::to_string(abi::isa::Flag flag) { if (flag == abi::isa::ZERO) { return "zero"; } else if (flag == abi::isa::CARRY) { return "carry"; } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/flag_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_FLAG_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_FLAG_CONVERTER_H_ #include #include "abi/isa/flag.h" namespace upmem_sim::converter { class FlagConverter { public: static std::string to_string(abi::isa::Flag flag); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/instruction_converter.cc ================================================ #include "converter/instruction_converter.h" #include #include "converter/condition_converter.h" #include "converter/endian_converter.h" #include "converter/op_code_converter.h" #include "converter/reg_converter.h" #include "converter/suffix_converter.h" namespace upmem_sim::converter { std::string InstructionConverter::to_string( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << "[" << instruction->thread()->id() << "] "; ss << OpCodeConverter::to_string(instruction->op_code()) << ", "; ss << SuffixConverter::to_string(instruction->suffix()) << ", "; abi::instruction::Suffix suffix = instruction->suffix(); if (suffix == abi::instruction::RICI) { ss << to_string_rici(instruction); } else if (suffix == abi::instruction::RRI) { ss << to_string_rri(instruction); } else if (suffix == abi::instruction::RRIC) { ss << to_string_rric(instruction); } else if (suffix == abi::instruction::RRICI) { ss << to_string_rrici(instruction); } else if (suffix == abi::instruction::RRIF) { ss << to_string_rrif(instruction); } else if (suffix == abi::instruction::RRR) { ss << to_string_rrr(instruction); } else if (suffix == abi::instruction::RRRC) { ss << to_string_rrrc(instruction); } else if (suffix == abi::instruction::RRRCI) { ss << to_string_rrrci(instruction); } else if (suffix == abi::instruction::ZRI) { ss << to_string_zri(instruction); } else if (suffix == abi::instruction::ZRIC) { ss << to_string_zric(instruction); } else if (suffix == abi::instruction::ZRICI) { ss << to_string_zrici(instruction); } else if (suffix == abi::instruction::ZRIF) { ss << to_string_zrif(instruction); } else if (suffix == abi::instruction::ZRR) { ss << to_string_zrr(instruction); } else if (suffix == abi::instruction::ZRRC) { ss << to_string_zrrc(instruction); } else if (suffix == abi::instruction::ZRRCI) { ss << to_string_zrrci(instruction); } else if (suffix == abi::instruction::S_RRI or suffix == abi::instruction::U_RRI) { ss << to_string_s_rri(instruction); } else if (suffix == abi::instruction::S_RRIC or suffix == abi::instruction::U_RRIC) { ss << to_string_s_rric(instruction); } else if (suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRICI) { ss << to_string_s_rrici(instruction); } else if (suffix == abi::instruction::S_RRIF or suffix == abi::instruction::U_RRIF) { ss << to_string_s_rrif(instruction); } else if (suffix == abi::instruction::S_RRR or suffix == abi::instruction::U_RRR) { ss << to_string_s_rrr(instruction); } else if (suffix == abi::instruction::S_RRRC or suffix == abi::instruction::U_RRRC) { ss << to_string_s_rrrc(instruction); } else if (suffix == abi::instruction::S_RRRCI or suffix == abi::instruction::U_RRRCI) { ss << to_string_s_rrrci(instruction); } else if (suffix == abi::instruction::RR) { ss << to_string_rr(instruction); } else if (suffix == abi::instruction::RRC) { ss << to_string_rrc(instruction); } else if (suffix == abi::instruction::RRCI) { ss << to_string_rrci(instruction); } else if (suffix == abi::instruction::ZR) { ss << to_string_zr(instruction); } else if (suffix == abi::instruction::ZRC) { ss << to_string_zrc(instruction); } else if (suffix == abi::instruction::ZRCI) { ss << to_string_zrci(instruction); } else if (suffix == abi::instruction::S_RR or suffix == abi::instruction::U_RR) { ss << to_string_s_rr(instruction); } else if (suffix == abi::instruction::S_RRC or suffix == abi::instruction::U_RRC) { ss << to_string_s_rrc(instruction); } else if (suffix == abi::instruction::S_RRCI or suffix == abi::instruction::U_RRCI) { ss << to_string_s_rrci(instruction); } else if (suffix == abi::instruction::DRDICI) { ss << to_string_drdici(instruction); } else if (suffix == abi::instruction::RRRI) { ss << to_string_rrri(instruction); } else if (suffix == abi::instruction::RRRICI) { ss << to_string_rrrici(instruction); } else if (suffix == abi::instruction::ZRRI) { ss << to_string_zrri(instruction); } else if (suffix == abi::instruction::ZRRICI) { ss << to_string_zrrici(instruction); } else if (suffix == abi::instruction::S_RRRI or suffix == abi::instruction::U_RRRI) { ss << to_string_s_rrri(instruction); } else if (suffix == abi::instruction::S_RRRICI or suffix == abi::instruction::U_RRRICI) { ss << to_string_s_rrici(instruction); } else if (suffix == abi::instruction::RIR) { ss << to_string_rir(instruction); } else if (suffix == abi::instruction::RIRC) { ss << to_string_rirc(instruction); } else if (suffix == abi::instruction::RIRCI) { ss << to_string_rirci(instruction); } else if (suffix == abi::instruction::ZIR) { ss << to_string_zir(instruction); } else if (suffix == abi::instruction::ZIRC) { ss << to_string_zirc(instruction); } else if (suffix == abi::instruction::ZIRCI) { ss << to_string_zirci(instruction); } else if (suffix == abi::instruction::S_RIRC or suffix == abi::instruction::U_RIRC) { ss << to_string_rirc(instruction); } else if (suffix == abi::instruction::S_RIRCI or suffix == abi::instruction::U_RIRCI) { ss << to_string_rirci(instruction); } else if (suffix == abi::instruction::R) { ss << to_string_r(instruction); } else if (suffix == abi::instruction::RCI) { ss << to_string_rci(instruction); } else if (suffix == abi::instruction::Z) { ss << to_string_z(instruction); } else if (suffix == abi::instruction::ZCI) { ss << to_string_zci(instruction); } else if (suffix == abi::instruction::S_R or suffix == abi::instruction::U_R) { ss << to_string_s_r(instruction); } else if (suffix == abi::instruction::S_RCI or suffix == abi::instruction::U_RCI) { ss << to_string_s_rci(instruction); } else if (suffix == abi::instruction::CI) { ss << to_string_ci(instruction); } else if (suffix == abi::instruction::I) { ss << to_string_i(instruction); } else if (suffix == abi::instruction::DDCI) { ss << to_string_ddci(instruction); } else if (suffix == abi::instruction::ERRI) { ss << to_string_erri(instruction); } else if (suffix == abi::instruction::S_ERRI or suffix == abi::instruction::U_ERRI) { ss << to_string_s_erri(instruction); } else if (suffix == abi::instruction::EDRI) { ss << to_string_edri(instruction); } else if (suffix == abi::instruction::ERII) { ss << to_string_erii(instruction); } else if (suffix == abi::instruction::ERIR) { ss << to_string_erir(instruction); } else if (suffix == abi::instruction::ERID) { ss << to_string_erid(instruction); } else if (suffix == abi::instruction::DMA_RRI) { ss << to_string_dma_rri(instruction); } else { throw std::invalid_argument(""); } return ss.str(); } std::string InstructionConverter::to_string_rici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_rri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_rric( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_rrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_rrif( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_rrr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()); return ss.str(); } std::string InstructionConverter::to_string_rrrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_rrrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_zri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_zric( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_zrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_zrif( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_zrr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()); return ss.str(); } std::string InstructionConverter::to_string_zrrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_zrrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rric( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_s_rrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rrif( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rrr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()); return ss.str(); } std::string InstructionConverter::to_string_s_rrrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_s_rrrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_rr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()); return ss.str(); } std::string InstructionConverter::to_string_rrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_rrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_zr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()); return ss.str(); } std::string InstructionConverter::to_string_zrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_zrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rr( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()); return ss.str(); } std::string InstructionConverter::to_string_s_rrc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_s_rrci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_drdici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->db()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_rrri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_rrrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_zrri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_zrrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rrri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rrrici( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value() << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_rir( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()); return ss.str(); } std::string InstructionConverter::to_string_rirc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_rirci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_zir( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()); return ss.str(); } std::string InstructionConverter::to_string_zirc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_zirci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_rirc( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()); return ss.str(); } std::string InstructionConverter::to_string_s_rirci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << instruction->imm()->value() << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_r( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()); return ss.str(); } std::string InstructionConverter::to_string_rci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_z( abi::instruction::Instruction *instruction) { std::stringstream ss; return ss.str(); } std::string InstructionConverter::to_string_zci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_r( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()); return ss.str(); } std::string InstructionConverter::to_string_s_rci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_ci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_i( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_ddci( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->db()) << ", "; ss << ConditionConverter::to_string(instruction->condition()) << ", "; ss << instruction->pc()->value(); return ss.str(); } std::string InstructionConverter::to_string_erri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->rc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value(); return ss.str(); } std::string InstructionConverter::to_string_s_erri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value(); return ss.str(); } std::string InstructionConverter::to_string_edri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->dc()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value(); return ss.str(); } std::string InstructionConverter::to_string_erii( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value() << ", "; ss << instruction->imm()->value(); return ss.str(); } std::string InstructionConverter::to_string_erir( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value() << ", "; ss << RegConverter::to_string(instruction->rb()); return ss.str(); } std::string InstructionConverter::to_string_erid( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << EndianConverter::to_string(instruction->endian()) << ", "; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << instruction->off()->value() << ", "; ss << RegConverter::to_string(instruction->db()); return ss.str(); } std::string InstructionConverter::to_string_dma_rri( abi::instruction::Instruction *instruction) { std::stringstream ss; ss << RegConverter::to_string(instruction->ra()) << ", "; ss << RegConverter::to_string(instruction->rb()) << ", "; ss << instruction->imm()->value(); return ss.str(); } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/instruction_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_INSTRUCTION_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_INSTRUCTION_CONVERTER_H_ #include #include "abi/instruction/instruction.h" namespace upmem_sim::converter { class InstructionConverter { public: static std::string to_string(abi::instruction::Instruction *instruction); protected: static std::string to_string_rici(abi::instruction::Instruction *instruction); static std::string to_string_rri(abi::instruction::Instruction *instruction); static std::string to_string_rric(abi::instruction::Instruction *instruction); static std::string to_string_rrici( abi::instruction::Instruction *instruction); static std::string to_string_rrif(abi::instruction::Instruction *instruction); static std::string to_string_rrr(abi::instruction::Instruction *instruction); static std::string to_string_rrrc(abi::instruction::Instruction *instruction); static std::string to_string_rrrci( abi::instruction::Instruction *instruction); static std::string to_string_zri(abi::instruction::Instruction *instruction); static std::string to_string_zric(abi::instruction::Instruction *instruction); static std::string to_string_zrici( abi::instruction::Instruction *instruction); static std::string to_string_zrif(abi::instruction::Instruction *instruction); static std::string to_string_zrr(abi::instruction::Instruction *instruction); static std::string to_string_zrrc(abi::instruction::Instruction *instruction); static std::string to_string_zrrci( abi::instruction::Instruction *instruction); static std::string to_string_s_rri( abi::instruction::Instruction *instruction); static std::string to_string_s_rric( abi::instruction::Instruction *instruction); static std::string to_string_s_rrici( abi::instruction::Instruction *instruction); static std::string to_string_s_rrif( abi::instruction::Instruction *instruction); static std::string to_string_s_rrr( abi::instruction::Instruction *instruction); static std::string to_string_s_rrrc( abi::instruction::Instruction *instruction); static std::string to_string_s_rrrci( abi::instruction::Instruction *instruction); static std::string to_string_rr(abi::instruction::Instruction *instruction); static std::string to_string_rrc(abi::instruction::Instruction *instruction); static std::string to_string_rrci(abi::instruction::Instruction *instruction); static std::string to_string_zr(abi::instruction::Instruction *instruction); static std::string to_string_zrc(abi::instruction::Instruction *instruction); static std::string to_string_zrci(abi::instruction::Instruction *instruction); static std::string to_string_s_rr(abi::instruction::Instruction *instruction); static std::string to_string_s_rrc( abi::instruction::Instruction *instruction); static std::string to_string_s_rrci( abi::instruction::Instruction *instruction); static std::string to_string_drdici( abi::instruction::Instruction *instruction); static std::string to_string_rrri(abi::instruction::Instruction *instruction); static std::string to_string_rrrici( abi::instruction::Instruction *instruction); static std::string to_string_zrri(abi::instruction::Instruction *instruction); static std::string to_string_zrrici( abi::instruction::Instruction *instruction); static std::string to_string_s_rrri( abi::instruction::Instruction *instruction); static std::string to_string_s_rrrici( abi::instruction::Instruction *instruction); static std::string to_string_rir(abi::instruction::Instruction *instruction); static std::string to_string_rirc(abi::instruction::Instruction *instruction); static std::string to_string_rirci( abi::instruction::Instruction *instruction); static std::string to_string_zir(abi::instruction::Instruction *instruction); static std::string to_string_zirc(abi::instruction::Instruction *instruction); static std::string to_string_zirci( abi::instruction::Instruction *instruction); static std::string to_string_s_rirc( abi::instruction::Instruction *instruction); static std::string to_string_s_rirci( abi::instruction::Instruction *instruction); static std::string to_string_r(abi::instruction::Instruction *instruction); static std::string to_string_rci(abi::instruction::Instruction *instruction); static std::string to_string_z(abi::instruction::Instruction *instruction); static std::string to_string_zci(abi::instruction::Instruction *instruction); static std::string to_string_s_r(abi::instruction::Instruction *instruction); static std::string to_string_s_rci( abi::instruction::Instruction *instruction); static std::string to_string_ci(abi::instruction::Instruction *instruction); static std::string to_string_i(abi::instruction::Instruction *instruction); static std::string to_string_ddci(abi::instruction::Instruction *instruction); static std::string to_string_erri(abi::instruction::Instruction *instruction); static std::string to_string_s_erri( abi::instruction::Instruction *instruction); static std::string to_string_edri(abi::instruction::Instruction *instruction); static std::string to_string_erii(abi::instruction::Instruction *instruction); static std::string to_string_erir(abi::instruction::Instruction *instruction); static std::string to_string_erid(abi::instruction::Instruction *instruction); static std::string to_string_dma_rri( abi::instruction::Instruction *instruction); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/op_code_converter.cc ================================================ #include "converter/op_code_converter.h" #include namespace upmem_sim::converter { std::string OpCodeConverter::to_string(abi::instruction::OpCode op_code) { if (op_code == abi::instruction::ACQUIRE) { return "acquire"; } else if (op_code == abi::instruction::RELEASE) { return "release"; } else if (op_code == abi::instruction::ADD) { return "add"; } else if (op_code == abi::instruction::ADDC) { return "addc"; } else if (op_code == abi::instruction::AND) { return "and"; } else if (op_code == abi::instruction::ANDN) { return "andn"; } else if (op_code == abi::instruction::ASR) { return "asr"; } else if (op_code == abi::instruction::CAO) { return "cao"; } else if (op_code == abi::instruction::CLO) { return "clo"; } else if (op_code == abi::instruction::CLS) { return "cls"; } else if (op_code == abi::instruction::CLZ) { return "clz"; } else if (op_code == abi::instruction::CMPB4) { return "cmpb4"; } else if (op_code == abi::instruction::DIV_STEP) { return "div_step"; } else if (op_code == abi::instruction::EXTSB) { return "extsb"; } else if (op_code == abi::instruction::EXTSH) { return "extsh"; } else if (op_code == abi::instruction::EXTUB) { return "extub"; } else if (op_code == abi::instruction::EXTUH) { return "extuh"; } else if (op_code == abi::instruction::LSL) { return "lsl"; } else if (op_code == abi::instruction::LSL_ADD) { return "lsl_add"; } else if (op_code == abi::instruction::LSL_SUB) { return "lsl_sub"; } else if (op_code == abi::instruction::LSL1) { return "lsl1"; } else if (op_code == abi::instruction::LSL1X) { return "lsl1x"; } else if (op_code == abi::instruction::LSLX) { return "lslx"; } else if (op_code == abi::instruction::LSR) { return "lsr"; } else if (op_code == abi::instruction::LSR_ADD) { return "lsr_add"; } else if (op_code == abi::instruction::LSR1) { return "lsr1"; } else if (op_code == abi::instruction::LSR1X) { return "lsr1x"; } else if (op_code == abi::instruction::LSRX) { return "lsrx"; } else if (op_code == abi::instruction::MUL_SH_SH) { return "mul_sh_sh"; } else if (op_code == abi::instruction::MUL_SH_SL) { return "mul_sh_sl"; } else if (op_code == abi::instruction::MUL_SH_UH) { return "mul_sh_uh"; } else if (op_code == abi::instruction::MUL_SH_UL) { return "mul_sh_ul"; } else if (op_code == abi::instruction::MUL_SL_SH) { return "mul_sl_sh"; } else if (op_code == abi::instruction::MUL_SL_SL) { return "mul_sl_sl"; } else if (op_code == abi::instruction::MUL_SL_UH) { return "mul_sl_uh"; } else if (op_code == abi::instruction::MUL_SL_UL) { return "mul_sl_ul"; } else if (op_code == abi::instruction::MUL_STEP) { return "mul_step"; } else if (op_code == abi::instruction::MUL_UH_UH) { return "mul_uh_uh"; } else if (op_code == abi::instruction::MUL_UH_UL) { return "mul_uh_ul"; } else if (op_code == abi::instruction::MUL_UL_UH) { return "mul_ul_uh"; } else if (op_code == abi::instruction::MUL_UL_UL) { return "mul_ul_ul"; } else if (op_code == abi::instruction::NAND) { return "nand"; } else if (op_code == abi::instruction::NOR) { return "nor"; } else if (op_code == abi::instruction::NXOR) { return "nxor"; } else if (op_code == abi::instruction::OR) { return "or"; } else if (op_code == abi::instruction::ORN) { return "orn"; } else if (op_code == abi::instruction::ROL) { return "rol"; } else if (op_code == abi::instruction::ROL_ADD) { return "rol_add"; } else if (op_code == abi::instruction::ROR) { return "ror"; } else if (op_code == abi::instruction::RSUB) { return "rsub"; } else if (op_code == abi::instruction::RSUBC) { return "rsubc"; } else if (op_code == abi::instruction::SUB) { return "sub"; } else if (op_code == abi::instruction::SUBC) { return "subc"; } else if (op_code == abi::instruction::XOR) { return "xor"; } else if (op_code == abi::instruction::BOOT) { return "boot"; } else if (op_code == abi::instruction::RESUME) { return "resume"; } else if (op_code == abi::instruction::STOP) { return "stop"; } else if (op_code == abi::instruction::CALL) { return "call"; } else if (op_code == abi::instruction::FAULT) { return "fault"; } else if (op_code == abi::instruction::NOP) { return "nop"; } else if (op_code == abi::instruction::SATS) { return "sats"; } else if (op_code == abi::instruction::MOVD) { return "movd"; } else if (op_code == abi::instruction::SWAPD) { return "swapd"; } else if (op_code == abi::instruction::HASH) { return "hash"; } else if (op_code == abi::instruction::TIME) { return "time"; } else if (op_code == abi::instruction::TIME_CFG) { return "time_cfg"; } else if (op_code == abi::instruction::LBS) { return "lbs"; } else if (op_code == abi::instruction::LBU) { return "lbu"; } else if (op_code == abi::instruction::LD) { return "ld"; } else if (op_code == abi::instruction::LHS) { return "lhs"; } else if (op_code == abi::instruction::LHU) { return "lhu"; } else if (op_code == abi::instruction::LW) { return "lw"; } else if (op_code == abi::instruction::SB) { return "sb"; } else if (op_code == abi::instruction::SB_ID) { return "sb_id"; } else if (op_code == abi::instruction::SD) { return "sd"; } else if (op_code == abi::instruction::SD_ID) { return "sd_id"; } else if (op_code == abi::instruction::SH) { return "sh"; } else if (op_code == abi::instruction::SH_ID) { return "sh_id"; } else if (op_code == abi::instruction::SW) { return "sw"; } else if (op_code == abi::instruction::SW_ID) { return "sw_id"; } else if (op_code == abi::instruction::LDMA) { return "ldma"; } else if (op_code == abi::instruction::LDMAI) { return "ldmai"; } else if (op_code == abi::instruction::SDMA) { return "sdma"; } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/op_code_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_OP_CODE_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_OP_CODE_CONVERTER_H_ #include #include "abi/instruction/op_code.h" namespace upmem_sim::converter { class OpCodeConverter { public: static std::string to_string(abi::instruction::OpCode op_code); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/reg_converter.cc ================================================ #include "converter/reg_converter.h" #include namespace upmem_sim::converter { std::string RegConverter::to_string(abi::reg::SPReg sp_reg) { if (sp_reg == abi::reg::ZERO) { return "zero"; } else if (sp_reg == abi::reg::ONE) { return "one"; } else if (sp_reg == abi::reg::LNEG) { return "lneg"; } else if (sp_reg == abi::reg::MNEG) { return "mneg"; } else if (sp_reg == abi::reg::ID) { return "id"; } else if (sp_reg == abi::reg::ID2) { return "id2"; } else if (sp_reg == abi::reg::ID4) { return "id4"; } else if (sp_reg == abi::reg::ID8) { return "id8"; } else { throw std::invalid_argument(""); } } std::string RegConverter::to_string(abi::reg::SrcReg *src_reg) { if (src_reg->is_gp_reg()) { return to_string(src_reg->gp_reg()); } else if (src_reg->is_sp_reg()) { return to_string(*src_reg->sp_reg()); } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/reg_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_REG_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_REG_CONVERTER_H_ #include #include "abi/reg/gp_reg.h" #include "abi/reg/pair_reg.h" #include "abi/reg/sp_reg.h" #include "abi/reg/src_reg.h" namespace upmem_sim::converter { class RegConverter { public: static std::string to_string(abi::reg::GPReg *gp_reg) { return "r" + std::to_string(gp_reg->index()); } static std::string to_string(abi::reg::PairReg *pair_reg) { return "d" + std::to_string(pair_reg->even_reg()->index()); } static std::string to_string(abi::reg::SPReg sp_reg); static std::string to_string(abi::reg::SrcReg *src_reg); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/reg_file_converter.cc ================================================ #include "converter/reg_file_converter.h" #include #include "converter/condition_converter.h" #include "converter/flag_converter.h" #include "converter/reg_converter.h" namespace upmem_sim::converter { std::string RegFileConverter::to_string(simulator::reg::RegFile *reg_file) { std::stringstream ss; for (RegIndex index = 0; index < util::ConfigLoader::num_gp_registers(); index++) { auto gp_reg = new abi::reg::GPReg(index); ss << RegConverter::to_string(gp_reg) << ": " << reg_file->read_gp_reg(gp_reg, abi::word::SIGNED) << std::endl; delete gp_reg; } /* ss << "pc: " << reg_file->read_pc_reg() << std::endl; for (abi::isa::Condition condition = abi::isa::TRUE; condition != abi::isa::LARGE; condition = static_cast(condition + 1)) { ss << ConditionConverter::to_string(condition) << ": " << reg_file->condition(condition) << std::endl; } for (abi::isa::Flag flag = abi::isa::ZERO; flag != abi::isa::CARRY; flag = static_cast(flag + 1)) { ss << FlagConverter::to_string(flag) << ": " << reg_file->flag(flag) << std::endl; } */ return ss.str(); } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/reg_file_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_REG_FILE_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_REG_FILE_CONVERTER_H_ #include #include "simulator/reg/reg_file.h" namespace upmem_sim::converter { class RegFileConverter { public: static std::string to_string(simulator::reg::RegFile *reg_file); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/suffix_converter.cc ================================================ #include "converter/suffix_converter.h" #include namespace upmem_sim::converter { std::string SuffixConverter::to_string(abi::instruction::Suffix suffix) { if (suffix == abi::instruction::RICI) { return "rici"; } else if (suffix == abi::instruction::RRI) { return "rri"; } else if (suffix == abi::instruction::RRIC) { return "rric"; } else if (suffix == abi::instruction::RRICI) { return "rrici"; } else if (suffix == abi::instruction::RRIF) { return "rrif"; } else if (suffix == abi::instruction::RRR) { return "rrr"; } else if (suffix == abi::instruction::RRRC) { return "rrrc"; } else if (suffix == abi::instruction::RRRCI) { return "rrrci"; } else if (suffix == abi::instruction::ZRI) { return "zri"; } else if (suffix == abi::instruction::ZRIC) { return "zric"; } else if (suffix == abi::instruction::ZRICI) { return "zrici"; } else if (suffix == abi::instruction::ZRIF) { return "zrif"; } else if (suffix == abi::instruction::ZRR) { return "zrr"; } else if (suffix == abi::instruction::ZRRC) { return "zrrc"; } else if (suffix == abi::instruction::ZRRCI) { return "zrrci"; } else if (suffix == abi::instruction::S_RRI) { return "s_rri"; } else if (suffix == abi::instruction::S_RRIC) { return "s_rric"; } else if (suffix == abi::instruction::S_RRICI) { return "s_rrici"; } else if (suffix == abi::instruction::S_RRIF) { return "s_rrif"; } else if (suffix == abi::instruction::S_RRR) { return "s_rrr"; } else if (suffix == abi::instruction::S_RRRC) { return "s_rrrc"; } else if (suffix == abi::instruction::S_RRRCI) { return "s_rrrci"; } else if (suffix == abi::instruction::U_RRI) { return "u_rri"; } else if (suffix == abi::instruction::U_RRIC) { return "u_rric"; } else if (suffix == abi::instruction::U_RRICI) { return "u_rrici"; } else if (suffix == abi::instruction::U_RRIF) { return "u_rrif"; } else if (suffix == abi::instruction::U_RRR) { return "u_rrr"; } else if (suffix == abi::instruction::U_RRRC) { return "u_rrrc"; } else if (suffix == abi::instruction::U_RRRCI) { return "u_rrrci"; } else if (suffix == abi::instruction::RR) { return "rr"; } else if (suffix == abi::instruction::RRC) { return "rrc"; } else if (suffix == abi::instruction::RRCI) { return "rrci"; } else if (suffix == abi::instruction::ZR) { return "zr"; } else if (suffix == abi::instruction::ZRC) { return "zrc"; } else if (suffix == abi::instruction::ZRCI) { return "zrci"; } else if (suffix == abi::instruction::S_RR) { return "s_rr"; } else if (suffix == abi::instruction::S_RRC) { return "s_rrc"; } else if (suffix == abi::instruction::S_RRCI) { return "s_rrci"; } else if (suffix == abi::instruction::U_RR) { return "u_rr"; } else if (suffix == abi::instruction::U_RRC) { return "u_rrc"; } else if (suffix == abi::instruction::U_RRCI) { return "u_rrci"; } else if (suffix == abi::instruction::DRDICI) { return "drdici"; } else if (suffix == abi::instruction::RRRI) { return "rrri"; } else if (suffix == abi::instruction::RRRICI) { return "rrrici"; } else if (suffix == abi::instruction::ZRRI) { return "zrri"; } else if (suffix == abi::instruction::ZRRICI) { return "zrrici"; } else if (suffix == abi::instruction::S_RRRI) { return "s_rrri"; } else if (suffix == abi::instruction::S_RRRICI) { return "s_rrrici"; } else if (suffix == abi::instruction::U_RRRI) { return "u_rrri"; } else if (suffix == abi::instruction::U_RRRICI) { return "u_rrrici"; } else if (suffix == abi::instruction::RIR) { return "rir"; } else if (suffix == abi::instruction::RIRC) { return "rirc"; } else if (suffix == abi::instruction::RIRCI) { return "rirci"; } else if (suffix == abi::instruction::ZIR) { return "zir"; } else if (suffix == abi::instruction::ZIRC) { return "zirc"; } else if (suffix == abi::instruction::ZIRCI) { return "zirci"; } else if (suffix == abi::instruction::S_RIRC) { return "s_rirc"; } else if (suffix == abi::instruction::S_RIRCI) { return "s_rirci"; } else if (suffix == abi::instruction::U_RIRC) { return "u_rirc"; } else if (suffix == abi::instruction::U_RIRCI) { return "u_rirci"; } else if (suffix == abi::instruction::R) { return "r"; } else if (suffix == abi::instruction::RCI) { return "rci"; } else if (suffix == abi::instruction::Z) { return "z"; } else if (suffix == abi::instruction::ZCI) { return "zci"; } else if (suffix == abi::instruction::S_R) { return "s_r"; } else if (suffix == abi::instruction::S_RCI) { return "s_rci"; } else if (suffix == abi::instruction::U_R) { return "u_r"; } else if (suffix == abi::instruction::U_RCI) { return "u_rci"; } else if (suffix == abi::instruction::CI) { return "ci"; } else if (suffix == abi::instruction::I) { return "i"; } else if (suffix == abi::instruction::DDCI) { return "ddci"; } else if (suffix == abi::instruction::ERRI) { return "erri"; } else if (suffix == abi::instruction::S_ERRI) { return "s_erri"; } else if (suffix == abi::instruction::U_ERRI) { return "u_erri"; } else if (suffix == abi::instruction::EDRI) { return "edri"; } else if (suffix == abi::instruction::ERII) { return "erii"; } else if (suffix == abi::instruction::ERIR) { return "erir"; } else if (suffix == abi::instruction::ERID) { return "erid"; } else if (suffix == abi::instruction::DMA_RRI) { return "dma_rri"; } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::converter ================================================ FILE: python_cpp/uPIMulator_backend/src/converter/suffix_converter.h ================================================ #ifndef UPMEM_SIM_CONVERTER_SUFFIX_CONVERTER_H_ #define UPMEM_SIM_CONVERTER_SUFFIX_CONVERTER_H_ #include #include "abi/instruction/suffix.h" namespace upmem_sim::converter { class SuffixConverter { public: static std::string to_string(abi::instruction::Suffix suffix); }; } // namespace upmem_sim::converter #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/encoder/byte.h ================================================ #ifndef UPMEM_SIM_ENCODER_BYTE_H_ #define UPMEM_SIM_ENCODER_BYTE_H_ #include namespace upmem_sim::encoder { class Byte { public: explicit Byte(int value) : value_(value) { assert(0 <= value and value < 256); } ~Byte() = default; int value() { return value_; } private: int value_; }; } // namespace upmem_sim::encoder #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/encoder/byte_stream.cc ================================================ #include "encoder/byte_stream.h" #include namespace upmem_sim::encoder { ByteStream::ByteStream(std::vector bytes) { bytes_.resize(bytes.size()); for (int i = 0; i < bytes_.size(); i++) { bytes_[i] = new Byte(bytes[i]); } } ByteStream::ByteStream(std::string filename) { std::ifstream ifs(filename); int byte; while (ifs >> byte) { append(byte); } } ByteStream::~ByteStream() { for (auto &byte : bytes_) { delete byte; } } std::vector ByteStream::bytes() { std::vector bytes; bytes.resize(bytes_.size()); for (int i = 0; i < size(); i++) { bytes[i] = byte(i); } return std::move(bytes); } void ByteStream::merge(ByteStream *byte_stream) { int size = static_cast(bytes_.size()); bytes_.resize(bytes_.size() + byte_stream->bytes_.size()); for (int i = 0; i < byte_stream->size(); i++) { bytes_[i + size] = new Byte(static_cast(byte_stream->byte(i))); } } ByteStream *ByteStream::slice(int begin, int end) { assert(0 <= begin and begin < end and end <= size()); auto *byte_stream = new ByteStream(); for (int i = begin; i < end; i++) { byte_stream->append(byte(i)); } return byte_stream; } } // namespace upmem_sim::encoder ================================================ FILE: python_cpp/uPIMulator_backend/src/encoder/byte_stream.h ================================================ #ifndef UPMEM_SIM_ENCODER_BYTE_STREAM_H_ #define UPMEM_SIM_ENCODER_BYTE_STREAM_H_ #include #include #include "encoder/byte.h" #include "main.h" namespace upmem_sim::encoder { class ByteStream { public: explicit ByteStream() = default; explicit ByteStream(std::vector bytes); explicit ByteStream(std::string filename); ~ByteStream(); Address size() { return static_cast(bytes_.size()); } int byte(int index) { return bytes_[index]->value(); } std::vector bytes(); void append(int value) { bytes_.push_back(new Byte(value)); } void merge(ByteStream *byte_stream); ByteStream *slice(int begin, int end); private: std::vector bytes_; }; } // namespace upmem_sim::encoder #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/encoder/instruction_encoder.cc ================================================ #include "encoder/instruction_encoder.h" #include namespace upmem_sim::encoder { abi::instruction::Instruction *InstructionEncoder::decode( ByteStream *byte_stream) { auto instruction_word = new abi::word::InstructionWord(); instruction_word->from_byte_stream(byte_stream); abi::instruction::OpCode op_code = decode_op_code(instruction_word); abi::instruction::Suffix suffix = decode_suffix(instruction_word); abi::instruction::Instruction *instruction = nullptr; if (suffix == abi::instruction::RICI) { instruction = decode_rici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRI) { instruction = decode_rri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRIC) { instruction = decode_rric(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRICI) { instruction = decode_rrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRIF) { instruction = decode_rrif(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRR) { instruction = decode_rrr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRRC) { instruction = decode_rrrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRRCI) { instruction = decode_rrrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRI) { instruction = decode_zri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRIC) { instruction = decode_zric(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRICI) { instruction = decode_zrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRIF) { instruction = decode_zrif(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRR) { instruction = decode_zrr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRRC) { instruction = decode_zrrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRRCI) { instruction = decode_zrrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRI or suffix == abi::instruction::U_RRI) { instruction = decode_s_rri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRIC or suffix == abi::instruction::U_RRIC) { instruction = decode_s_rric(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRICI) { instruction = decode_s_rrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRIF or suffix == abi::instruction::U_RRIF) { instruction = decode_s_rrif(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRR or suffix == abi::instruction::U_RRR) { instruction = decode_s_rrr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRRC or suffix == abi::instruction::U_RRRC) { instruction = decode_s_rrrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRRCI or suffix == abi::instruction::U_RRRCI) { instruction = decode_s_rrrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RR) { instruction = decode_rr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRC) { instruction = decode_rrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRCI) { instruction = decode_rrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZR) { instruction = decode_zr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRC) { instruction = decode_zrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRCI) { instruction = decode_zrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RR or suffix == abi::instruction::U_RR) { instruction = decode_s_rr(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRC or suffix == abi::instruction::U_RRC) { instruction = decode_s_rrc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRCI or suffix == abi::instruction::U_RRCI) { instruction = decode_s_rrci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::DRDICI) { instruction = decode_drdici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRRI) { instruction = decode_rrri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RRRICI) { instruction = decode_rrrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRRI) { instruction = decode_zrri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZRRICI) { instruction = decode_zrrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRRI or suffix == abi::instruction::U_RRRI) { instruction = decode_s_rrri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RRRICI or suffix == abi::instruction::U_RRRICI) { instruction = decode_s_rrrici(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RIR) { instruction = decode_rir(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RIRC) { instruction = decode_rirc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RIRCI) { instruction = decode_rirci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZIR) { instruction = decode_zir(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZIRC) { instruction = decode_zirc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZIRCI) { instruction = decode_zirci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RIRC or suffix == abi::instruction::U_RIRC) { instruction = decode_s_rirc(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RIRCI or suffix == abi::instruction::U_RIRCI) { instruction = decode_s_rirci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::R) { instruction = decode_r(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::RCI) { instruction = decode_rci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::Z) { instruction = decode_z(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ZCI) { instruction = decode_zci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_R or suffix == abi::instruction::U_R) { instruction = decode_s_r(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_RCI or suffix == abi::instruction::U_RCI) { instruction = decode_s_rci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::CI) { instruction = decode_ci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::I) { instruction = decode_i(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::DDCI) { instruction = decode_ddci(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ERRI) { instruction = decode_erri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::S_ERRI or suffix == abi::instruction::U_ERRI) { instruction = decode_s_erri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::EDRI) { instruction = decode_edri(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ERII) { instruction = decode_erii(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ERIR) { instruction = decode_erir(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::ERID) { instruction = decode_erid(op_code, suffix, instruction_word); } else if (suffix == abi::instruction::DMA_RRI) { instruction = decode_dma_rri(op_code, suffix, instruction_word); } else { throw std::invalid_argument(""); } delete instruction_word; return instruction; } abi::instruction::OpCode InstructionEncoder::decode_op_code( abi::word::InstructionWord *instruction_word) { return static_cast(instruction_word->bit_slice( abi::word::UNSIGNED, op_code_begin(), op_code_end())); } abi::instruction::Suffix InstructionEncoder::decode_suffix( abi::word::InstructionWord *instruction_word) { return static_cast(instruction_word->bit_slice( abi::word::UNSIGNED, suffix_begin(), suffix_end())); } abi::reg::GPReg *InstructionEncoder::decode_gp_reg( abi::word::InstructionWord *instruction_word, int begin, int end) { auto index = static_cast( instruction_word->bit_slice(abi::word::UNSIGNED, begin, end)); return new abi::reg::GPReg(index); } abi::reg::SrcReg *InstructionEncoder::decode_src_reg( abi::word::InstructionWord *instruction_word, int begin, int end) { auto index = static_cast( instruction_word->bit_slice(abi::word::UNSIGNED, begin, end)); if (index < util::ConfigLoader::num_gp_registers()) { return new abi::reg::SrcReg(new abi::reg::GPReg(index)); } else { return new abi::reg::SrcReg( new abi::reg::SPReg(static_cast( index - util::ConfigLoader::num_gp_registers()))); } } abi::reg::PairReg *InstructionEncoder::decode_pair_reg( abi::word::InstructionWord *instruction_word, int begin, int end) { auto index = static_cast( instruction_word->bit_slice(abi::word::UNSIGNED, begin, end)); return new abi::reg::PairReg(index); } int64_t InstructionEncoder::decode_imm( abi::word::InstructionWord *instruction_word, int begin, int end, abi::word::Representation representation) { return instruction_word->bit_slice(representation, begin, end); } int64_t InstructionEncoder::decode_off( abi::word::InstructionWord *instruction_word, int begin, int end, abi::word::Representation representation) { return decode_imm(instruction_word, begin, end, representation); } abi::isa::Condition InstructionEncoder::decode_condition( abi::word::InstructionWord *instruction_word, int begin, int end) { return static_cast( instruction_word->bit_slice(abi::word::UNSIGNED, begin, end)); } int64_t InstructionEncoder::decode_pc( abi::word::InstructionWord *instruction_word, int begin, int end) { return decode_imm(instruction_word, begin, end, abi::word::UNSIGNED); } abi::isa::Endian InstructionEncoder::decode_endian( abi::word::InstructionWord *instruction_word, int begin, int end) { return static_cast( instruction_word->bit_slice(abi::word::UNSIGNED, begin, end)); } abi::instruction::Instruction *InstructionEncoder::decode_rici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rici_op_codes().count(op_code)); assert(suffix == abi::instruction::RICI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end = imm_begin + 16; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, ra, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rri_op_codes().count(op_code)); assert(suffix == abi::instruction::RRI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { imm_end = imm_begin + 32; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::call_rri_op_codes().count( op_code)) { imm_end = imm_begin + 24; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); } else { throw std::invalid_argument(""); } return new abi::instruction::Instruction(op_code, suffix, rc, ra, imm); } abi::instruction::Instruction *InstructionEncoder::decode_rric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rric_op_codes().count(op_code)); assert(suffix == abi::instruction::RRIC); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rric_op_codes().count(op_code) or abi::instruction::Instruction::sub_rric_op_codes().count(op_code)) { imm_end = imm_begin + 24; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_rrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrici_op_codes().count(op_code)); assert(suffix == abi::instruction::RRICI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code) or abi::instruction::Instruction::and_rrici_op_codes().count(op_code) or abi::instruction::Instruction::sub_rrici_op_codes().count(op_code)) { imm_end = imm_begin + 8; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_rrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrif_op_codes().count(op_code)); assert(suffix == abi::instruction::RRIF); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_rrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrr_op_codes().count(op_code)); assert(suffix == abi::instruction::RRR); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, rb); } abi::instruction::Instruction *InstructionEncoder::decode_rrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrc_op_codes().count(op_code)); assert(suffix == abi::instruction::RRRC); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, rb, condition); } abi::instruction::Instruction *InstructionEncoder::decode_rrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrci_op_codes().count(op_code)); assert(suffix == abi::instruction::RRRCI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, rb, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_zri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rri_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { imm_end = imm_begin + 32; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::call_rri_op_codes().count( op_code)) { imm_end = imm_begin + 28; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); } else { throw std::invalid_argument(""); } return new abi::instruction::Instruction(op_code, suffix, ra, imm); } abi::instruction::Instruction *InstructionEncoder::decode_zric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rric_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRIC); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rric_op_codes().count(op_code) or abi::instruction::Instruction::sub_rric_op_codes().count(op_code)) { imm_end = imm_begin + 27; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_zrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrici_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRICI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code) or abi::instruction::Instruction::and_rrici_op_codes().count(op_code) or abi::instruction::Instruction::sub_rrici_op_codes().count(op_code)) { imm_end = imm_begin + 11; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, ra, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_zrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrif_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRIF); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_zrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrr_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRR); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); return new abi::instruction::Instruction(op_code, suffix, ra, rb); } abi::instruction::Instruction *InstructionEncoder::decode_zrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrc_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRRC); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, ra, rb, condition); } abi::instruction::Instruction *InstructionEncoder::decode_zrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrci_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRRCI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, ra, rb, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rri_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRI or suffix == abi::instruction::U_RRI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { imm_end = imm_begin + 32; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::call_rri_op_codes().count( op_code)) { imm_end = imm_begin + 24; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); } else { throw std::invalid_argument(""); } return new abi::instruction::Instruction(op_code, suffix, dc, ra, imm); } abi::instruction::Instruction *InstructionEncoder::decode_s_rric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rric_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRIC or suffix == abi::instruction::U_RRIC); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rric_op_codes().count(op_code) or abi::instruction::Instruction::sub_rric_op_codes().count(op_code)) { imm_end = imm_begin + 24; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrici_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRICI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end; int64_t imm; if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code) or abi::instruction::Instruction::and_rrici_op_codes().count(op_code) or abi::instruction::Instruction::sub_rrici_op_codes().count(op_code)) { imm_end = imm_begin + 8; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { imm_end = imm_begin + 5; imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); } else { throw std::invalid_argument(""); } int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrif_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRIF or suffix == abi::instruction::U_RRIF); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int imm_begin = ra_end; int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, imm, condition); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrr_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRR or suffix == abi::instruction::U_RRR); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, rb); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrc_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRRC or suffix == abi::instruction::U_RRRC); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, rb, condition); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrci_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRRCI or suffix == abi::instruction::U_RRRCI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int condition_begin = rb_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, rb, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_rr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rr_op_codes().count(op_code)); assert(suffix == abi::instruction::RR); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra); } abi::instruction::Instruction *InstructionEncoder::decode_rrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrc_op_codes().count(op_code)); assert(suffix == abi::instruction::RRC); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_rrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrci_op_codes().count(op_code)); assert(suffix == abi::instruction::RRCI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_zr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rr_op_codes().count(op_code)); assert(suffix == abi::instruction::ZR); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); return new abi::instruction::Instruction(op_code, suffix, ra); } abi::instruction::Instruction *InstructionEncoder::decode_zrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrc_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRC); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_zrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrci_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRCI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rr_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RR or suffix == abi::instruction::U_RR); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrc_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRC or suffix == abi::instruction::U_RRC); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrci_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRCI or suffix == abi::instruction::U_RRCI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_drdici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::drdici_op_codes().count(op_code)); assert(suffix == abi::instruction::DRDICI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int db_begin = ra_end; int db_end = db_begin + register_width(); abi::reg::PairReg *db = decode_pair_reg(instruction_word, db_begin, db_end); int imm_begin = db_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, db, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_rrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrri_op_codes().count(op_code)); assert(suffix == abi::instruction::RRRI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); return new abi::instruction::Instruction(op_code, suffix, rc, ra, rb, imm); } abi::instruction::Instruction *InstructionEncoder::decode_rrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrici_op_codes().count(op_code)); assert(suffix == abi::instruction::RRRICI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, ra, rb, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_zrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrri_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRRI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); return new abi::instruction::Instruction(op_code, suffix, ra, rb, imm); } abi::instruction::Instruction *InstructionEncoder::decode_zrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrici_op_codes().count(op_code)); assert(suffix == abi::instruction::ZRRICI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, ra, rb, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrri_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRRI or suffix == abi::instruction::U_RRRI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); return new abi::instruction::Instruction(op_code, suffix, dc, ra, rb, imm); } abi::instruction::Instruction *InstructionEncoder::decode_s_rrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rrrici_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRRICI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 5; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int condition_begin = imm_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, ra, rb, imm, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_rir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rir_op_codes().count(op_code)); assert(suffix == abi::instruction::RIR); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int imm_begin = rc_end; int imm_end = imm_begin + 32; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); return new abi::instruction::Instruction(op_code, suffix, rc, imm, ra); } abi::instruction::Instruction *InstructionEncoder::decode_rirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirc_op_codes().count(op_code)); assert(suffix == abi::instruction::RIRC); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int imm_begin = rc_end; int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, rc, imm, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_rirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirci_op_codes().count(op_code)); assert(suffix == abi::instruction::RIRCI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int imm_begin = rc_end; int imm_end = imm_begin + 8; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, imm, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_zir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rir_op_codes().count(op_code)); assert(suffix == abi::instruction::ZIR); int imm_begin = suffix_end(); int imm_end = imm_begin + 32; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); return new abi::instruction::Instruction(op_code, suffix, imm, ra); } abi::instruction::Instruction *InstructionEncoder::decode_zirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirc_op_codes().count(op_code)); assert(suffix == abi::instruction::ZIRC); int imm_begin = suffix_end(); int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, imm, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_zirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirci_op_codes().count(op_code)); assert(suffix == abi::instruction::ZIRCI); int imm_begin = suffix_end(); int imm_end = imm_begin + 8; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, imm, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirc_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RIRC or suffix == abi::instruction::U_RIRC); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int imm_begin = dc_end; int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); return new abi::instruction::Instruction(op_code, suffix, dc, imm, ra, condition); } abi::instruction::Instruction *InstructionEncoder::decode_s_rirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rirci_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RIRCI or suffix == abi::instruction::U_RIRCI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int imm_begin = dc_end; int imm_end = imm_begin + 8; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); int ra_begin = imm_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int condition_begin = ra_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, imm, ra, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_r( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::r_op_codes().count(op_code)); assert(suffix == abi::instruction::R); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); return new abi::instruction::Instruction(op_code, suffix, rc); } abi::instruction::Instruction *InstructionEncoder::decode_rci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rci_op_codes().count(op_code)); assert(suffix == abi::instruction::RCI); int rc_begin = suffix_end(); int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int condition_begin = rc_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, rc, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_z( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::r_op_codes().count(op_code) or op_code == abi::instruction::NOP); assert(suffix == abi::instruction::Z); return new abi::instruction::Instruction(op_code, suffix); } abi::instruction::Instruction *InstructionEncoder::decode_zci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rci_op_codes().count(op_code)); assert(suffix == abi::instruction::ZCI); int condition_begin = suffix_end(); int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_s_r( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::r_op_codes().count(op_code)); assert(suffix == abi::instruction::S_R or suffix == abi::instruction::U_R); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); return new abi::instruction::Instruction(op_code, suffix, dc); } abi::instruction::Instruction *InstructionEncoder::decode_s_rci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::rci_op_codes().count(op_code)); assert(suffix == abi::instruction::S_RCI or suffix == abi::instruction::U_RCI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int condition_begin = dc_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_ci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::ci_op_codes().count(op_code)); assert(suffix == abi::instruction::CI); int condition_begin = suffix_end(); int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_i( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::i_op_codes().count(op_code)); assert(suffix == abi::instruction::I); int imm_begin = suffix_end(); int imm_end = imm_begin + 24; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); return new abi::instruction::Instruction(op_code, suffix, imm); } abi::instruction::Instruction *InstructionEncoder::decode_ddci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::ddci_op_codes().count(op_code)); assert(suffix == abi::instruction::DDCI); int dc_begin = suffix_end(); int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int db_begin = dc_end; int db_end = db_begin + register_width(); abi::reg::PairReg *db = decode_pair_reg(instruction_word, db_begin, db_end); int condition_begin = db_end; int condition_end = condition_begin + condition_width(); abi::isa::Condition condition = decode_condition(instruction_word, condition_begin, condition_end); int pc_begin = condition_end; int pc_end = pc_begin + pc_width(); int64_t pc = decode_pc(instruction_word, pc_begin, pc_end); return new abi::instruction::Instruction(op_code, suffix, dc, db, condition, pc); } abi::instruction::Instruction *InstructionEncoder::decode_erri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::erri_op_codes().count(op_code)); assert(suffix == abi::instruction::ERRI); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int rc_begin = endian_end; int rc_end = rc_begin + register_width(); abi::reg::GPReg *rc = decode_gp_reg(instruction_word, rc_begin, rc_end); int ra_begin = rc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); return new abi::instruction::Instruction(op_code, suffix, endian, rc, ra, off); } abi::instruction::Instruction *InstructionEncoder::decode_s_erri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::erri_op_codes().count(op_code)); assert(suffix == abi::instruction::S_ERRI or suffix == abi::instruction::U_ERRI); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int dc_begin = endian_end; int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); return new abi::instruction::Instruction(op_code, suffix, endian, dc, ra, off); } abi::instruction::Instruction *InstructionEncoder::decode_edri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::edri_op_codes().count(op_code)); assert(suffix == abi::instruction::EDRI); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int dc_begin = endian_end; int dc_end = dc_begin + register_width(); abi::reg::PairReg *dc = decode_pair_reg(instruction_word, dc_begin, dc_end); int ra_begin = dc_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); return new abi::instruction::Instruction(op_code, suffix, endian, dc, ra, off); } abi::instruction::Instruction *InstructionEncoder::decode_erii( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::erii_op_codes().count(op_code)); assert(suffix == abi::instruction::ERII); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int ra_begin = endian_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); int imm_begin = off_end; int imm_end = imm_begin + 16; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::SIGNED); return new abi::instruction::Instruction(op_code, suffix, endian, ra, off, imm); } abi::instruction::Instruction *InstructionEncoder::decode_erir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::erir_op_codes().count(op_code)); assert(suffix == abi::instruction::ERIR); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int ra_begin = endian_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); int rb_begin = off_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); return new abi::instruction::Instruction(op_code, suffix, endian, ra, off, rb); } abi::instruction::Instruction *InstructionEncoder::decode_erid( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::erid_op_codes().count(op_code)); assert(suffix == abi::instruction::ERID); int endian_begin = suffix_end(); int endian_end = endian_begin + endian_width(); abi::isa::Endian endian = decode_endian(instruction_word, endian_begin, endian_end); int ra_begin = endian_end; int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int off_begin = ra_end; int off_end = off_begin + 24; int64_t off = decode_off(instruction_word, off_begin, off_end, abi::word::SIGNED); int db_begin = off_end; int db_end = db_begin + register_width(); abi::reg::PairReg *db = decode_pair_reg(instruction_word, db_begin, db_end); return new abi::instruction::Instruction(op_code, suffix, endian, ra, off, db); } abi::instruction::Instruction *InstructionEncoder::decode_dma_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word) { assert(abi::instruction::Instruction::dma_rri_op_codes().count(op_code)); assert(suffix == abi::instruction::DMA_RRI); int ra_begin = suffix_end(); int ra_end = ra_begin + register_width(); abi::reg::SrcReg *ra = decode_src_reg(instruction_word, ra_begin, ra_end); int rb_begin = ra_end; int rb_end = rb_begin + register_width(); abi::reg::SrcReg *rb = decode_src_reg(instruction_word, rb_begin, rb_end); int imm_begin = rb_end; int imm_end = imm_begin + 8; int64_t imm = decode_imm(instruction_word, imm_begin, imm_end, abi::word::UNSIGNED); return new abi::instruction::Instruction(op_code, suffix, ra, rb, imm); } } // namespace upmem_sim::encoder ================================================ FILE: python_cpp/uPIMulator_backend/src/encoder/instruction_encoder.h ================================================ #ifndef UPMEM_SIM_ENCODER_INSTRUCTION_ENCODER_H_ #define UPMEM_SIM_ENCODER_INSTRUCTION_ENCODER_H_ #include #include "abi/instruction/instruction.h" #include "abi/instruction/op_code.h" #include "abi/instruction/suffix.h" #include "abi/word/instruction_word.h" #include "encoder/byte_stream.h" #include "util/config_loader.h" namespace upmem_sim::encoder { class InstructionEncoder { public: static abi::instruction::Instruction *decode(ByteStream *byte_stream); protected: static abi::instruction::OpCode decode_op_code( abi::word::InstructionWord *instruction_word); static abi::instruction::Suffix decode_suffix( abi::word::InstructionWord *instruction_word); static abi::reg::GPReg *decode_gp_reg( abi::word::InstructionWord *instruction_word, int begin, int end); static abi::reg::SrcReg *decode_src_reg( abi::word::InstructionWord *instruction_word, int begin, int end); static abi::reg::PairReg *decode_pair_reg( abi::word::InstructionWord *instruction_word, int begin, int end); static int64_t decode_imm(abi::word::InstructionWord *instruction_word, int begin, int end, abi::word::Representation representation); static int64_t decode_off(abi::word::InstructionWord *instruction_word, int begin, int end, abi::word::Representation representation); static abi::isa::Condition decode_condition( abi::word::InstructionWord *instruction_word, int begin, int end); static int64_t decode_pc(abi::word::InstructionWord *instruction_word, int begin, int end); static abi::isa::Endian decode_endian( abi::word::InstructionWord *instruction_word, int begin, int end); static abi::instruction::Instruction *decode_rici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rric( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrif( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rr( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_drdici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rrrici( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rirc( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rirci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_r( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_rci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_z( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_zci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_r( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_rci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_ci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_i( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_ddci( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_erri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_s_erri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_edri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_erii( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_erir( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_erid( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static abi::instruction::Instruction *decode_dma_rri( abi::instruction::OpCode op_code, abi::instruction::Suffix suffix, abi::word::InstructionWord *instruction_word); static int op_code_begin() { return 0; } static int op_code_end() { return op_code_begin() + op_code_width(); } static int suffix_begin() { return op_code_end(); } static int suffix_end() { return suffix_begin() + suffix_width(); } static int op_code_width() { return ceil(log2(1.0 + abi::instruction::SDMA)); } static int suffix_width() { return ceil(log2(1.0 + abi::instruction::DMA_RRI)); } static int register_width() { return ceil(log2(util::ConfigLoader::num_gp_registers() + abi::reg::ID8)); } static int condition_width() { return ceil(log2(1.0 + abi::isa::LARGE)); } static int pc_width() { return util::ConfigLoader::iram_address_width(); } static int endian_width() { return ceil(log2(1.0 + abi::isa::BIG)); } }; } // namespace upmem_sim::encoder #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/initializer/int_initializer.cc ================================================ #include "initializer/int_initializer.h" #include #include #include namespace upmem_sim::initializer { int64_t IntInitializer::value_by_range(int64_t min_value, int64_t max_value) { assert(min_value < max_value); std::random_device random_device; std::mt19937 generator(random_device()); std::uniform_int_distribution distribution; int64_t range = max_value - min_value; return distribution(generator) % range + min_value; } int64_t IntInitializer::value_by_width(abi::word::Representation representation, int width) { if (representation == abi::word::UNSIGNED) { return value_by_range(0, static_cast(pow(2, width))); } else { return value_by_range(-static_cast(pow(2, width - 1)), static_cast(pow(2, width - 1))); } } } // namespace upmem_sim::initializer ================================================ FILE: python_cpp/uPIMulator_backend/src/initializer/int_initializer.h ================================================ #ifndef UPMEM_SIM_INITIALIZER_INT_INITIALIZER_H_ #define UPMEM_SIM_INITIALIZER_INT_INITIALIZER_H_ #include #include "abi/word/representation.h" namespace upmem_sim::initializer { class IntInitializer { public: static int64_t value_by_range(int64_t min_value, int64_t max_value); static int64_t value_by_width(abi::word::Representation representation, int width); }; } // namespace upmem_sim::initializer #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/initializer/str_initializer.h ================================================ #ifndef UPMEM_SIM_INITIALIZER_STR_INITIALIZER_H_ #define UPMEM_SIM_INITIALIZER_STR_INITIALIZER_H_ #include namespace upmem_sim::initializer { class StrInitializer { public: static std::string identifier(int width); }; } // namespace upmem_sim::initializer #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/initializer/str_initialzier.cc ================================================ #include #include #include #include "initializer/str_initializer.h" namespace upmem_sim::initializer { std::string StrInitializer::identifier(int width) { assert(width > 0); std::string characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._"; std::random_device random_device; std::mt19937 generator(random_device()); std::uniform_int_distribution distribution; std::string identifier = ""; for (int i = 0; i < width; i++) { int index = static_cast(distribution(generator) % characters.length()); identifier += characters.substr(index, 1); } return identifier; } } // namespace upmem_sim::initializer ================================================ FILE: python_cpp/uPIMulator_backend/src/main.cc ================================================ #include #include "simulator/system.h" #include "util/argument_parser.h" namespace upmem_sim { util::ArgumentParser *init_argument_parser() { auto argument_parser = new util::ArgumentParser(); // NOTE(dongjae.lee@kaist.ac.kr): Explanation of verbose level // level 0: Only prints simulation output // level 1: level 0 + prints UPMEM instruction executed per each logic cycle // level 2: level + prints UPMEM register file values per each logic cycle argument_parser->add_option("verbose", util::ArgumentParser::INT, "0"); argument_parser->add_option("benchmark", util::ArgumentParser::STRING, "TRNS"); argument_parser->add_option("num_dpus", util::ArgumentParser::INT, "1"); argument_parser->add_option("num_tasklets", util::ArgumentParser::INT, "16"); argument_parser->add_option("bindir", util::ArgumentParser::STRING, "/home/via/uPIMulator_frontend/bin"); argument_parser->add_option("logdir", util::ArgumentParser::STRING, "/home/via/uPIMulator_backend/log"); argument_parser->add_option("logic_frequency", util::ArgumentParser::INT, "350"); argument_parser->add_option("memory_frequency", util::ArgumentParser::INT, "2400"); // based on DDR4-2400 argument_parser->add_option("num_pipeline_stages", util::ArgumentParser::INT, "14"); argument_parser->add_option("num_revolver_scheduling_cycles", util::ArgumentParser::INT, "11"); argument_parser->add_option("wordline_size", util::ArgumentParser::INT, "1024"); argument_parser->add_option("t_rcd", util::ArgumentParser::INT, "32"); // based on DDR4-2400 argument_parser->add_option("t_ras", util::ArgumentParser::INT, "78"); // based on DDR4-2400 argument_parser->add_option("t_rp", util::ArgumentParser::INT, "32"); // based on DDR4-2400 argument_parser->add_option("t_cl", util::ArgumentParser::INT, "32"); // based on DDR4-2400 argument_parser->add_option("t_bl", util::ArgumentParser::INT, "8"); // based on DDR4-2400 argument_parser->add_option("memory_scheduling_policy", util::ArgumentParser::STRING, "frfcfs"); argument_parser->add_option("rank_read_bandwidth", util::ArgumentParser::INT, "1"); //1 argument_parser->add_option("rank_write_bandwidth", util::ArgumentParser::INT, "3"); //3 return argument_parser; } } // namespace upmem_sim int main(int argc, char **argv) { upmem_sim::util::ArgumentParser *argument_parser = upmem_sim::init_argument_parser(); argument_parser->parse(argc, argv); auto system = new upmem_sim::simulator::System(argument_parser); system->init(); while (not system->is_finished()) { system->cycle(); } system->fini(); for (auto &option : argument_parser->options()) { if (argument_parser->option_type(option) == upmem_sim::util::ArgumentParser::INT) { std::cout << option << ": " << argument_parser->get_int_parameter(option) << std::endl; } else if (argument_parser->option_type(option) == upmem_sim::util::ArgumentParser::STRING) { std::cout << option << ": " << argument_parser->get_string_parameter(option) << std::endl; } else { throw std::invalid_argument(""); } } upmem_sim::util::StatFactory *system_stat_factory = system->stat_factory(); for (auto &stat : system_stat_factory->stats()) { std::cout << stat << ": " << system_stat_factory->value(stat) << std::endl; } delete system_stat_factory; delete argument_parser; delete system; return 0; } ================================================ FILE: python_cpp/uPIMulator_backend/src/main.h ================================================ #ifndef UPMEM_SIM_MAIN_H_ #define UPMEM_SIM_MAIN_H_ #include namespace upmem_sim { using SimTime = int64_t; using Address = int64_t; using DPUID = int; using ThreadID = int; using RegIndex = int; } // namespace upmem_sim #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/basic/queue.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_BASIC_QUEUE_H_ #define UPMEM_SIM_SIMULATOR_BASIC_QUEUE_H_ #include #include #include namespace upmem_sim::simulator::basic { template class Queue { public: explicit Queue(int size) : size_(size) { assert(size != 0); } ~Queue() { assert(q_.empty()); } bool empty() { return q_.empty(); } int size() { return q_.size(); } bool can_push(int num_items); bool can_push() { return can_push(1); } void push(T *item); bool can_pop() { return not q_.empty(); } T *pop(); void cycle() = delete; T *front(); private: int size_; std::queue q_; }; template bool Queue::can_push(int num_items) { if (size_ >= 0) { return size_ - q_.size() >= num_items; } else { return true; } } template void Queue::push(T *item) { assert(can_push()); q_.push(item); } template T *Queue::pop() { assert(can_pop()); T *item = q_.front(); q_.pop(); return item; } template T *Queue::front() { if (q_.empty()) { return nullptr; } else { return q_.front(); } } } // namespace upmem_sim::simulator::basic #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/basic/timer_queue.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_BASIC_TIMER_QUEUE_H_ #define UPMEM_SIM_SIMULATOR_BASIC_TIMER_QUEUE_H_ #include #include #include #include "main.h" namespace upmem_sim::simulator::basic { template class TimerQueue { public: explicit TimerQueue(int size); explicit TimerQueue(int size, SimTime timer); ~TimerQueue() { assert(q_.empty()); } bool empty() { return q_.empty(); } int size() { return q_.size(); } bool can_push(int num_items); bool can_push() { return can_push(1); } void push(T *item); void push(T *item, SimTime timer); bool can_pop(); T *pop(); void cycle(); std::tuple front(); private: int size_; SimTime timer_; std::vector> q_; }; template TimerQueue::TimerQueue(int size) : size_(size), timer_(0) { assert(size != 0); } template TimerQueue::TimerQueue(int size, SimTime timer) : size_(size), timer_(timer) { assert(size != 0); assert(timer > 0); } template bool TimerQueue::can_push(int num_items) { if (size_ >= 0) { return size_ - q_.size() >= num_items; } else { return true; } } template void TimerQueue::push(T *item) { assert(can_push()); push(item, timer_); } template void TimerQueue::push(T *item, SimTime timer) { assert(can_push()); q_.push_back({item, timer}); } template bool TimerQueue::can_pop() { if (q_.empty()) { return false; } else { auto [item, timer] = q_[0]; if (timer <= 0) { return true; } else { return false; } } } template T *TimerQueue::pop() { assert(can_pop()); auto [item, timer] = q_[0]; q_.erase(q_.begin()); return item; } template std::tuple TimerQueue::front() { if (q_.empty()) { return {nullptr, 0}; } else { return q_[0]; } } template void TimerQueue::cycle() { if (not q_.empty()) { auto &[item, timer] = q_[0]; timer -= 1; } } } // namespace upmem_sim::simulator::basic #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/cpu.cc ================================================ #include "simulator/cpu/cpu.h" namespace upmem_sim::simulator::cpu { CPU::~CPU() { delete init_thread_; delete sched_thread_; delete fini_thread_; } void CPU::connect_rank(rank::Rank* rank) { init_thread_->connect_rank(rank); sched_thread_->connect_rank(rank); fini_thread_->connect_rank(rank); } } // namespace upmem_sim::simulator::cpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/cpu.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_CPU_CPU_H_ #define UPMEM_SIM_SIMULATOR_CPU_CPU_H_ #include "simulator/cpu/fini_thread.h" #include "simulator/cpu/init_thread.h" #include "simulator/cpu/sched_thread.h" #include "simulator/rank/rank.h" namespace upmem_sim::simulator::cpu { class CPU { public: explicit CPU(util::ArgumentParser *argument_parser) : init_thread_(new InitThread(argument_parser)), sched_thread_(new SchedThread(argument_parser)), fini_thread_(new FiniThread(argument_parser)) {} ~CPU(); void connect_rank(rank::Rank *rank); int num_executions() { return fini_thread_->num_executions(); } void init() { init_thread_->init(); } void launch() { init_thread_->launch(); } void sched(int execution) { sched_thread_->sched(execution); } void check(int execution) { sched_thread_->check(execution); } void fini() {} void cycle() { fini_thread_->cycle(); } private: InitThread *init_thread_; SchedThread *sched_thread_; FiniThread *fini_thread_; }; } // namespace upmem_sim::simulator::cpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/fini_thread.cc ================================================ #include "simulator/cpu/fini_thread.h" namespace upmem_sim::simulator::cpu { void FiniThread::connect_rank(rank::Rank *rank) { assert(rank != nullptr); assert(rank_ == nullptr); rank_ = rank; } void FiniThread::cycle() { for (auto &dpu : rank_->dpus()) { for (auto &thread : dpu->scheduler()->threads()) { if (thread->reg_file()->read_pc_reg() == sys_end_pointer() and thread->state() == dpu::Thread::SLEEP) { dpu->scheduler()->shutdown(thread->id()); } } } } } // namespace upmem_sim::simulator::cpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/fini_thread.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_CPU_FINI_THREAD_H_ #define UPMEM_SIM_SIMULATOR_CPU_FINI_THREAD_H_ #include "simulator/cpu/thread.h" #include "simulator/rank/rank.h" namespace upmem_sim::simulator::cpu { class FiniThread : public Thread { public: explicit FiniThread(util::ArgumentParser *argument_parser) : Thread(argument_parser), rank_(nullptr) {} ~FiniThread() = default; void connect_rank(rank::Rank *rank); void fini() = delete; void cycle(); private: rank::Rank *rank_; }; } // namespace upmem_sim::simulator::cpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/init_thread.cc ================================================ #include "simulator/cpu/init_thread.h" #include namespace upmem_sim::simulator::cpu { void InitThread::connect_rank(rank::Rank *rank) { assert(rank != nullptr); assert(rank_ == nullptr); rank_ = rank; } void InitThread::init() { dma_transfer_to_atomic(); dma_transfer_to_iram(); dma_transfer_to_wram(); dma_transfer_to_mram(); std::cout << "init completed..." << std::endl; } void InitThread::launch() { rank_->launch(); std::cout << "launch completed..." << std::endl; } void InitThread::dma_transfer_to_atomic() { auto byte_stream = load_byte_stream("atomic"); for (auto &dpu : rank_->dpus()) { dpu->dma()->transfer_to_atomic(util::ConfigLoader::atomic_offset(), byte_stream); } delete byte_stream; std::cout << "DMA to atomic completed..." << std::endl; } void InitThread::dma_transfer_to_iram() { auto byte_stream = load_byte_stream("iram"); for (auto &dpu : rank_->dpus()) { dpu->dma()->transfer_to_iram(util::ConfigLoader::iram_offset(), byte_stream); } delete byte_stream; std::cout << "DMA to IRAM completed..." << std::endl; } void InitThread::dma_transfer_to_wram() { auto byte_stream = load_byte_stream("wram"); for (auto &dpu : rank_->dpus()) { dpu->dma()->transfer_to_wram(util::ConfigLoader::wram_offset(), byte_stream); } delete byte_stream; std::cout << "DMA to WRAM completed..." << std::endl; } void InitThread::dma_transfer_to_mram() { auto byte_stream = load_byte_stream("mram"); for (auto &dpu : rank_->dpus()) { dpu->dma()->transfer_to_mram(util::ConfigLoader::mram_offset(), byte_stream); } delete byte_stream; std::cout << "DMA to MRAM completed..." << std::endl; } } // namespace upmem_sim::simulator::cpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/init_thread.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_CPU_INIT_THREAD_H_ #define UPMEM_SIM_SIMULATOR_CPU_INIT_THREAD_H_ #include "simulator/cpu/thread.h" #include "simulator/rank/rank.h" namespace upmem_sim::simulator::cpu { class InitThread : public Thread { public: explicit InitThread(util::ArgumentParser *argument_parser) : Thread(argument_parser), rank_(nullptr) {} ~InitThread() = default; void connect_rank(rank::Rank *rank); void init(); void launch(); void cycle() = delete; protected: void dma_transfer_to_atomic(); void dma_transfer_to_iram(); void dma_transfer_to_wram(); void dma_transfer_to_mram(); private: rank::Rank *rank_; }; } // namespace upmem_sim::simulator::cpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/sched_thread.cc ================================================ #include "simulator/cpu/sched_thread.h" #include #include #include "main.h" namespace upmem_sim::simulator::cpu { void SchedThread::connect_rank(rank::Rank *rank) { assert(rank != nullptr); assert(rank_ == nullptr); rank_ = rank; } void SchedThread::sched(int execution) { dma_transfer_input_dpu_mram_heap_pointer_name(execution); dma_transfer_dpu_input_arguments(execution); std::cout << "sched " << execution << " completed..." << std::endl; } void SchedThread::check(int execution) { dma_transfer_output_dpu_mram_heap_pointer_name(execution); dma_transfer_dpu_results(execution); std::cout << "check " << execution << " completed..." << std::endl; } void SchedThread::dma_transfer_input_dpu_mram_heap_pointer_name(int execution) { std::set rank_messages; for (DPUID dpu_id = 0; dpu_id < num_dpus(); dpu_id++) { std::stringstream ss; ss << "input_dpu_mram_heap_pointer_name.dpu_id" << dpu_id << "." << execution; std::string bin_filename; ss >> bin_filename; auto byte_stream = load_byte_stream(bin_filename); if (byte_stream != nullptr) { auto rank_message = new rank::RankMessage( rank::RankMessage::WRITE, dpu_id, sys_used_mram_end_pointer(), byte_stream->size(), byte_stream); rank_->write(rank_message); rank_messages.insert(rank_message); rank_->dpus()[dpu_id]->dma()->transfer_to_mram( sys_used_mram_end_pointer(), byte_stream); delete byte_stream; } } for (auto & rank_message : rank_messages) { while (not rank_message->ack()) { rank_->cycle(); } delete rank_message; } } void SchedThread::dma_transfer_dpu_input_arguments(int execution) { std::set rank_messages; for (DPUID dpu_id = 0; dpu_id < num_dpus(); dpu_id++) { std::stringstream ss; ss << "dpu_input_arguments.dpu_id" << dpu_id << "." << execution; std::string bin_filename; ss >> bin_filename; auto byte_stream = load_byte_stream(bin_filename); if (byte_stream != nullptr) { auto rank_message = new rank::RankMessage( rank::RankMessage::WRITE, dpu_id, dpu_input_arguments_pointer(), byte_stream->size(), byte_stream); rank_->write(rank_message); rank_messages.insert(rank_message); rank_->dpus()[dpu_id]->dma()->transfer_to_wram( dpu_input_arguments_pointer(), byte_stream); delete byte_stream; } } for (auto & rank_message : rank_messages) { while (not rank_message->ack()) { rank_->cycle(); } delete rank_message; } } void SchedThread::dma_transfer_output_dpu_mram_heap_pointer_name( int execution) { std::set rank_messages; for (DPUID dpu_id = 0; dpu_id < num_dpus(); dpu_id++) { std::stringstream ss; ss << "output_dpu_mram_heap_pointer_name.dpu_id" << dpu_id << "." << execution; std::string bin_filename; ss >> bin_filename; auto byte_stream = load_byte_stream(bin_filename); if (byte_stream != nullptr) { auto rank_message = new rank::RankMessage(rank::RankMessage::READ, dpu_id, sys_used_mram_end_pointer(), byte_stream->size()); rank_->read(rank_message); rank_messages.insert(rank_message); encoder::ByteStream *mram_byte_stream = rank_->dpus()[dpu_id]->dma()->transfer_from_mram( sys_used_mram_end_pointer(), byte_stream->size()); assert(byte_stream->size() == mram_byte_stream->size()); for (int i = 0; i < byte_stream->size(); i++) { assert(byte_stream->byte(i) == mram_byte_stream->byte(i)); } delete byte_stream; delete mram_byte_stream; } } for (auto & rank_message : rank_messages) { while (not rank_message->ack()) { rank_->cycle(); } delete rank_message; } } void SchedThread::dma_transfer_dpu_results(int execution) { std::set rank_messages; for (DPUID dpu_id = 0; dpu_id < num_dpus(); dpu_id++) { std::stringstream ss; ss << "dpu_results.dpu_id" << dpu_id << "." << execution; std::string bin_filename; ss >> bin_filename; auto byte_stream = load_byte_stream(bin_filename); if (byte_stream != nullptr) { auto rank_message = new rank::RankMessage(rank::RankMessage::READ, dpu_id, dpu_results_pointer(), byte_stream->size()); rank_->read(rank_message); rank_messages.insert(rank_message); encoder::ByteStream *wram_byte_stream = rank_->dpus()[dpu_id]->dma()->transfer_from_wram( dpu_results_pointer(), byte_stream->size()); assert(byte_stream->size() == wram_byte_stream->size()); for (int i = 0; i < byte_stream->size(); i++) { assert(byte_stream->byte(i) == wram_byte_stream->byte(i)); } delete byte_stream; delete wram_byte_stream; } } for (auto & rank_message : rank_messages) { while (not rank_message->ack()) { rank_->cycle(); } delete rank_message; } } } // namespace upmem_sim::simulator::cpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/sched_thread.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_CPU_SCHED_THREAD_H_ #define UPMEM_SIM_SIMULATOR_CPU_SCHED_THREAD_H_ #include "simulator/cpu/thread.h" #include "simulator/rank/rank.h" namespace upmem_sim::simulator::cpu { class SchedThread : public Thread { public: explicit SchedThread(util::ArgumentParser *argument_parser) : Thread(argument_parser), rank_(nullptr) {} ~SchedThread() = default; void connect_rank(rank::Rank *rank); void sched(int execution); void check(int execution); void cycle() = delete; protected: void dma_transfer_input_dpu_mram_heap_pointer_name(int execution); void dma_transfer_dpu_input_arguments(int execution); void dma_transfer_output_dpu_mram_heap_pointer_name(int execution); void dma_transfer_dpu_results(int execution); private: rank::Rank *rank_; }; } // namespace upmem_sim::simulator::cpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/thread.cc ================================================ #include "simulator/cpu/thread.h" #include #include #include namespace upmem_sim::simulator::cpu { Thread::Thread(util::ArgumentParser *argument_parser) : bindir_(argument_parser->get_string_parameter("bindir")), benchmark_(argument_parser->get_string_parameter("benchmark")), num_dpus_( static_cast(argument_parser->get_int_parameter("num_dpus"))), num_tasklets_(static_cast( argument_parser->get_int_parameter("num_tasklets"))) { assert(0 < num_dpus_); assert(0 < num_tasklets_ and num_tasklets_ <= util::ConfigLoader::max_num_tasklets()); init_dpu_transfer_pointer(); init_num_executions(); } encoder::ByteStream *Thread::load_byte_stream(std::string filename) { std::string bin_filepath = bindir_ + "/" + benchmark_ + "." + std::to_string(num_tasklets_) + "/" + filename + ".bin"; if (std::filesystem::exists(bin_filepath)) { auto byte_stream = new encoder::ByteStream(bin_filepath); return byte_stream; } else { return nullptr; } } void Thread::init_dpu_transfer_pointer() { std::string bin_filepath = bindir_ + "/" + benchmark_ + "." + std::to_string(num_tasklets_) + "/dpu_transfer_pointer.bin"; std::ifstream ifs(bin_filepath); ifs >> sys_used_mram_end_pointer_ >> dpu_input_arguments_pointer_ >> dpu_results_pointer_ >> sys_end_pointer_; } void Thread::init_num_executions() { std::string bin_filepath = bindir_ + "/" + benchmark_ + "." + std::to_string(num_tasklets_) + "/num_executions.bin"; std::ifstream ifs(bin_filepath); ifs >> num_executions_; } } // namespace upmem_sim::simulator::cpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/cpu/thread.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_CPU_THREAD_H_ #define UPMEM_SIM_SIMULATOR_CPU_THREAD_H_ #include "simulator/dpu/dpu.h" namespace upmem_sim::simulator::cpu { class Thread { public: explicit Thread(util::ArgumentParser *argument_parser); ~Thread() = default; std::string benchmark() { return benchmark_; } int num_dpus() { return num_dpus_; } int num_tasklets() { return num_tasklets_; } Address sys_used_mram_end_pointer() { return sys_used_mram_end_pointer_; } Address dpu_input_arguments_pointer() { return dpu_input_arguments_pointer_; } Address dpu_results_pointer() { return dpu_results_pointer_; } Address sys_end_pointer() { return sys_end_pointer_; } int num_executions() { return num_executions_; } protected: encoder::ByteStream *load_byte_stream(std::string filename); void init_dpu_transfer_pointer(); void init_num_executions(); private: std::string bindir_; std::string benchmark_; int num_dpus_; int num_tasklets_; Address sys_used_mram_end_pointer_; Address dpu_input_arguments_pointer_; Address dpu_results_pointer_; Address sys_end_pointer_; int num_executions_; }; } // namespace upmem_sim::simulator::cpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/alu.cc ================================================ #include "simulator/dpu/alu.h" #include #include #include #include "abi/word/data_word.h" namespace upmem_sim::simulator::dpu { int64_t ALU::atomic_address_hash(int64_t operand1, int64_t operand2) { assert(operand1 + operand2 < 256); auto [result, carry, overflow] = add(operand1, operand2); return result; } std::tuple ALU::add(int64_t operand1, int64_t operand2) { return addc(operand1, operand2, false); } std::tuple ALU::addc(int64_t operand1, int64_t operand2, bool carry_flag) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); int64_t result = data_word1->value(abi::word::UNSIGNED) + data_word2->value(abi::word::UNSIGNED) + carry_flag; int64_t max_unsigned_value = static_cast(pow(2, abi::word::DataWord().width())) - 1; bool carry; if (result > max_unsigned_value) { result %= static_cast(pow(2, abi::word::DataWord().width())); carry = true; } else { carry = false; } auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(result); bool overflow; if (data_word1->sign_bit() and data_word2->sign_bit() and not result_data_word->sign_bit()) { overflow = true; } else if (not data_word1->sign_bit() and not data_word2->sign_bit() and result_data_word->sign_bit()) { overflow = true; } else { overflow = false; } delete data_word1; delete data_word2; delete result_data_word; return {result, carry, overflow}; } std::tuple ALU::sub(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); int64_t result; bool carry; if (data_word1->value(abi::word::UNSIGNED) >= data_word2->value(abi::word::UNSIGNED)) { result = data_word1->value(abi::word::UNSIGNED) - data_word2->value(abi::word::UNSIGNED); carry = false; } else { result = static_cast(pow(2, abi::word::DataWord().width())) + data_word1->value(abi::word::UNSIGNED) - data_word2->value(abi::word::UNSIGNED); carry = true; } auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(result); bool overflow; if (data_word1->sign_bit() and not data_word2->sign_bit() and result_data_word->sign_bit()) { overflow = true; } else if (not data_word1->sign_bit() and data_word2->sign_bit() and not result_data_word->sign_bit()) { overflow = true; } else { overflow = false; } delete data_word1; delete data_word2; delete result_data_word; return {result, carry, overflow}; } std::tuple ALU::subc(int64_t operand1, int64_t operand2, bool carry_flag) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); int64_t result; bool carry; if (data_word1->value(abi::word::UNSIGNED) + carry_flag >= data_word2->value(abi::word::UNSIGNED)) { result = data_word1->value(abi::word::UNSIGNED) - data_word2->value(abi::word::UNSIGNED) - carry_flag; carry = false; } else { result = static_cast(pow(2, abi::word::DataWord().width())) + data_word1->value(abi::word::UNSIGNED) - data_word2->value(abi::word::UNSIGNED) - carry_flag; carry = true; } auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(result); bool overflow; if (data_word1->sign_bit() and not data_word2->sign_bit() and result_data_word->sign_bit()) { overflow = true; } else if (not data_word1->sign_bit() and data_word2->sign_bit() and not result_data_word->sign_bit()) { overflow = true; } else { overflow = false; } delete data_word1; delete data_word2; delete result_data_word; return {result, carry, overflow}; } int64_t ALU::and_(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (data_word1->bit(i) and data_word2->bit(i)) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::nand(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (data_word1->bit(i) and data_word2->bit(i)) { result_data_word->clear_bit(i); } else { result_data_word->set_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::andn(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (not data_word1->bit(i) and data_word2->bit(i)) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::or_(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (data_word1->bit(i) or data_word2->bit(i)) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::nor(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (data_word1->bit(i) or data_word2->bit(i)) { result_data_word->clear_bit(i); } else { result_data_word->set_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::orn(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (not data_word1->bit(i) or data_word2->bit(i)) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::xor_(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (not data_word1->bit(i) and data_word2->bit(i)) { result_data_word->set_bit(i); } else if (data_word1->bit(i) and not data_word2->bit(i)) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::nxor(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (not data_word1->bit(i) and data_word2->bit(i)) { result_data_word->clear_bit(i); } else if (data_word1->bit(i) and not data_word2->bit(i)) { result_data_word->clear_bit(i); } else { result_data_word->set_bit(i); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::asr(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); bool msb = data_word->sign_bit(); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i + shift_value >= result_data_word->width()) { if (msb) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } else { if (data_word->bit(static_cast(i + shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } int64_t ALU::lsl(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i < shift_value) { result_data_word->clear_bit(i); } else { if (data_word->bit(static_cast(i - shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } std::tuple ALU::lsl_add(int64_t operand1, int64_t operand2, int64_t shift) { return add(operand1, lsl(operand2, shift)); } std::tuple ALU::lsl_sub(int64_t operand1, int64_t operand2, int64_t shift) { return sub(operand1, lsl(operand2, shift)); } int64_t ALU::lsl1(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i < shift_value) { result_data_word->set_bit(i); } else { if (data_word->bit(static_cast(i - shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } int64_t ALU::lsl1x(int64_t operand, int64_t shift) { throw std::bad_function_call(); } int64_t ALU::lslx(int64_t operand, int64_t shift) { auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); if (shift_value == 0) { return 0; } else { return lsr(operand, abi::word::DataWord().width() - shift_value); } } int64_t ALU::lsr(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i + shift_value >= result_data_word->width()) { result_data_word->clear_bit(i); } else { if (data_word->bit(static_cast(i + shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } std::tuple ALU::lsr_add(int64_t operand1, int64_t operand2, int64_t shift) { return add(operand1, lsr(operand2, shift)); } int64_t ALU::lsr1(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i + shift_value >= result_data_word->width()) { result_data_word->set_bit(i); } else { if (data_word->bit(static_cast(i + shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } int64_t ALU::lsr1x(int64_t operand, int64_t shift) { throw std::bad_function_call(); } int64_t ALU::lsrx(int64_t operand, int64_t shift) { auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); if (shift_value == 0) { return 0; } else { return lsl(operand, abi::word::DataWord().width() - shift_value); } } int64_t ALU::rol(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i < shift_value) { if (data_word->bit( static_cast(i + data_word->width() - shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } else { if (data_word->bit(static_cast(i - shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } std::tuple ALU::rol_add(int64_t operand1, int64_t operand2, int64_t shift) { return add(operand1, rol(operand2, shift)); } int64_t ALU::ror(int64_t operand, int64_t shift) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto shift_data_word = new abi::word::DataWord(); shift_data_word->set_value(shift); auto shift_value = shift_data_word->bit_slice(abi::word::UNSIGNED, 0, 5); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < result_data_word->width(); i++) { if (i + shift_value >= result_data_word->width()) { if (data_word->bit( static_cast((i + shift_value) % data_word->width()))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } else { if (data_word->bit(static_cast(i + shift_value))) { result_data_word->set_bit(i); } else { result_data_word->clear_bit(i); } } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word; delete result_data_word; return result; } int64_t ALU::cao(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t ones = 0; for (int i = 0; i < data_word->width(); i++) { if (data_word->bit(i)) { ones += 1; } } delete data_word; return ones; } int64_t ALU::clo(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t leading_ones = 0; for (int i = 0; i < data_word->width(); i++) { if (data_word->bit(data_word->width() - 1 - i)) { leading_ones += 1; } else { break; } } delete data_word; return leading_ones; } int64_t ALU::cls(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); bool msb = data_word->sign_bit(); int64_t leading_sign_bits = 0; for (int i = 0; i < data_word->width(); i++) { if (data_word->bit(data_word->width() - 1 - i) == msb) { leading_sign_bits += 1; } else { break; } } delete data_word; return leading_sign_bits; } int64_t ALU::clz(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t leading_zeros = 0; for (int i = 0; i < data_word->width(); i++) { if (not data_word->bit(data_word->width() - 1 - i)) { leading_zeros += 1; } else { break; } } delete data_word; return leading_zeros; } int64_t ALU::cmpb4(int64_t operand1, int64_t operand2) { assert(abi::word::DataWord().width() == 4 * 8); auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); for (int i = 0; i < 4; i++) { int begin = 8 * i; int end = 8 * (i + 1); int64_t byte1 = data_word1->bit_slice(abi::word::UNSIGNED, begin, end); int64_t byte2 = data_word2->bit_slice(abi::word::UNSIGNED, begin, end); if (byte1 == byte2) { result_data_word->set_bit_slice(begin, end, 1); } else { result_data_word->set_bit_slice(begin, end, 0); } } int64_t result = result_data_word->value(abi::word::UNSIGNED); delete result_data_word; return result; } int64_t ALU::extsb(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t result = data_word->bit_slice(abi::word::SIGNED, 0, 8); delete data_word; return result; } int64_t ALU::extsh(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t result = data_word->bit_slice(abi::word::SIGNED, 0, 16); delete data_word; return result; } int64_t ALU::extub(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t result = data_word->bit_slice(abi::word::UNSIGNED, 0, 8); delete data_word; return result; } int64_t ALU::extuh(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); int64_t result = data_word->bit_slice(abi::word::UNSIGNED, 0, 16); delete data_word; return result; } int64_t ALU::mul_sh_sh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 8, 16) * data_word2->bit_slice(abi::word::SIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sh_sl(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 8, 16) * data_word2->bit_slice(abi::word::UNSIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sh_uh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value( data_word1->bit_slice(abi::word::SIGNED, 8, 16) * data_word2->bit_slice(abi::word::UNSIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sh_ul(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 8, 16) * data_word2->bit_slice(abi::word::UNSIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sl_sh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 0, 8) * data_word2->bit_slice(abi::word::SIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sl_sl(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 0, 8) * data_word2->bit_slice(abi::word::SIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sl_uh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value( data_word1->bit_slice(abi::word::SIGNED, 0, 8) * data_word2->bit_slice(abi::word::UNSIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_sl_ul(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::SIGNED, 0, 8) * data_word2->bit_slice(abi::word::UNSIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::SIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_uh_uh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value( data_word1->bit_slice(abi::word::UNSIGNED, 8, 16) * data_word2->bit_slice(abi::word::UNSIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_uh_ul(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value( data_word1->bit_slice(abi::word::UNSIGNED, 8, 16) * data_word2->bit_slice(abi::word::UNSIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_ul_uh(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value( data_word1->bit_slice(abi::word::UNSIGNED, 0, 8) * data_word2->bit_slice(abi::word::UNSIGNED, 8, 16)); int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::mul_ul_ul(int64_t operand1, int64_t operand2) { auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(data_word1->bit_slice(abi::word::UNSIGNED, 0, 8) * data_word2->bit_slice(abi::word::UNSIGNED, 0, 8)); int64_t result = result_data_word->value(abi::word::UNSIGNED); delete data_word1; delete data_word2; delete result_data_word; return result; } int64_t ALU::sats(int64_t operand) { throw std::bad_function_call(); } int64_t ALU::hash(int64_t operand1, int64_t operand2) { throw std::bad_function_call(); } std::tuple ALU::signed_extension(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto even_data_word = new abi::word::DataWord(); if (data_word->sign_bit()) { even_data_word->set_value(-1); } int64_t even = even_data_word->value(abi::word::UNSIGNED); auto odd_data_word = new abi::word::DataWord(); odd_data_word->set_value(data_word->value(abi::word::UNSIGNED)); int64_t odd = odd_data_word->value(abi::word::UNSIGNED); delete data_word; delete even_data_word; delete odd_data_word; return {even, odd}; } std::tuple ALU::unsigned_extension(int64_t operand) { auto data_word = new abi::word::DataWord(); data_word->set_value(operand); auto even_data_word = new abi::word::DataWord(); even_data_word->set_value(0); int64_t even = even_data_word->value(abi::word::UNSIGNED); auto odd_data_word = new abi::word::DataWord(); odd_data_word->set_value(data_word->value(abi::word::UNSIGNED)); int64_t odd = odd_data_word->value(abi::word::UNSIGNED); delete data_word; delete even_data_word; delete odd_data_word; return {even, odd}; } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/alu.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_ALU_H_ #define UPMEM_SIM_SIMULATOR_DPU_ALU_H_ #include #include namespace upmem_sim::simulator::dpu { class ALU { public: static int64_t atomic_address_hash(int64_t operand1, int64_t operand2); static std::tuple add(int64_t operand1, int64_t operand2); static std::tuple addc(int64_t operand1, int64_t operand2, bool carry_flag); static std::tuple sub(int64_t operand1, int64_t operand2); static std::tuple subc(int64_t operand1, int64_t operand2, bool carry_flag); static int64_t and_(int64_t operand1, int64_t operand2); static int64_t nand(int64_t operand1, int64_t operand2); static int64_t andn(int64_t operand1, int64_t operand2); static int64_t or_(int64_t operand1, int64_t operand2); static int64_t nor(int64_t operand1, int64_t operand2); static int64_t orn(int64_t operand1, int64_t operand2); static int64_t xor_(int64_t operand1, int64_t operand2); static int64_t nxor(int64_t operand1, int64_t operand2); static int64_t asr(int64_t operand, int64_t shift); static int64_t lsl(int64_t operand, int64_t shift); static std::tuple lsl_add(int64_t operand1, int64_t operand2, int64_t shift); static std::tuple lsl_sub(int64_t operand1, int64_t operand2, int64_t shift); static int64_t lsl1(int64_t operand, int64_t shift); static int64_t lsl1x(int64_t operand, int64_t shift); static int64_t lslx(int64_t operand, int64_t shift); static int64_t lsr(int64_t operand, int64_t shift); static std::tuple lsr_add(int64_t operand1, int64_t operand2, int64_t shift); static int64_t lsr1(int64_t operand, int64_t shift); static int64_t lsr1x(int64_t operand, int64_t shift); static int64_t lsrx(int64_t operand, int64_t shift); static int64_t rol(int64_t operand, int64_t shift); static std::tuple rol_add(int64_t operand1, int64_t operand2, int64_t shift); static int64_t ror(int64_t operand, int64_t shift); static int64_t cao(int64_t operand); static int64_t clo(int64_t operand); static int64_t cls(int64_t operand); static int64_t clz(int64_t operand); static int64_t cmpb4(int64_t operand1, int64_t operand2); static int64_t extsb(int64_t operand); static int64_t extsh(int64_t operand); static int64_t extub(int64_t operand); static int64_t extuh(int64_t operand); static int64_t mul_sh_sh(int64_t operand1, int64_t operand2); static int64_t mul_sh_sl(int64_t operand1, int64_t operand2); static int64_t mul_sh_uh(int64_t operand1, int64_t operand2); static int64_t mul_sh_ul(int64_t operand1, int64_t operand2); static int64_t mul_sl_sh(int64_t operand1, int64_t operand2); static int64_t mul_sl_sl(int64_t operand1, int64_t operand2); static int64_t mul_sl_uh(int64_t operand1, int64_t operand2); static int64_t mul_sl_ul(int64_t operand1, int64_t operand2); static int64_t mul_uh_uh(int64_t operand1, int64_t operand2); static int64_t mul_uh_ul(int64_t operand1, int64_t operand2); static int64_t mul_ul_uh(int64_t operand1, int64_t operand2); static int64_t mul_ul_ul(int64_t operand1, int64_t operand2); static int64_t sats(int64_t operand); static int64_t hash(int64_t operand1, int64_t operand2); static std::tuple signed_extension(int64_t operand); static std::tuple unsigned_extension(int64_t operand); }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/cycle_rule.cc ================================================ #include "simulator/dpu/cycle_rule.h" namespace upmem_sim::simulator::dpu { CycleRule::CycleRule(util::ArgumentParser *argument_parser) : input_q_(new basic::Queue(1)), wait_q_(new basic::TimerQueue(1)), ready_q_(new basic::Queue(1)), stat_factory_(new util::StatFactory("CycleRule")) { int num_tasklets = static_cast(argument_parser->get_int_parameter("num_tasklets")); prev_write_gp_regs_.resize(num_tasklets); cur_read_gp_regs_.resize(num_tasklets); } CycleRule::~CycleRule() { delete input_q_; delete wait_q_; delete ready_q_; for (auto &prev_write_gp_regs : prev_write_gp_regs_) { for (auto &gp_reg : prev_write_gp_regs) { delete gp_reg; } } for (auto &cur_read_gp_regs : cur_read_gp_regs_) { for (auto &gp_reg : cur_read_gp_regs) { delete gp_reg; } } delete stat_factory_; } util::StatFactory *CycleRule::stat_factory() { auto stat_factory = new util::StatFactory(""); stat_factory->merge(stat_factory_); return stat_factory; } void CycleRule::push(abi::instruction::Instruction *instruction) { assert(instruction != nullptr); input_q_->push(instruction); } void CycleRule::cycle() { service_input_q(); service_ready_q(); wait_q_->cycle(); } void CycleRule::service_input_q() { if (input_q_->can_pop() and wait_q_->can_push()) { abi::instruction::Instruction *instruction = input_q_->pop(); int extra_cycle = calculate_extra_cycles(instruction); wait_q_->push(instruction, extra_cycle); stat_factory_->increment("cycle_rule", extra_cycle); stat_factory_->increment( std::to_string(instruction->thread()->id()) + "_cycle_rule", extra_cycle); } } void CycleRule::service_ready_q() { if (wait_q_->can_pop() and ready_q_->can_push()) { abi::instruction::Instruction *instruction = wait_q_->pop(); ready_q_->push(instruction); for (auto &gp_reg : prev_write_gp_regs_[instruction->thread()->id()]) { delete gp_reg; } prev_write_gp_regs_[instruction->thread()->id()].clear(); for (auto &gp_reg : cur_read_gp_regs_[instruction->thread()->id()]) { delete gp_reg; } cur_read_gp_regs_[instruction->thread()->id()].clear(); prev_write_gp_regs_[instruction->thread()->id()] = collect_write_gp_regs(instruction); } } int CycleRule::calculate_extra_cycles( abi::instruction::Instruction *instruction) { cur_read_gp_regs_[instruction->thread()->id()] = collect_read_gp_regs(instruction); auto [even_counter, odd_counter] = calculate_counters(instruction); return even_counter / 2 + odd_counter / 2; } std::tuple CycleRule::calculate_counters( abi::instruction::Instruction *instruction) { std::set registers = merge(prev_write_gp_regs_[instruction->thread()->id()], cur_read_gp_regs_[instruction->thread()->id()]); int even_counter = 0; int odd_counter = 0; for (auto ®ister_ : registers) { if (register_->index() % 2 == 0) { even_counter += 1; } else { odd_counter += 1; } } return {even_counter, odd_counter}; } std::set CycleRule::collect_read_gp_regs( abi::instruction::Instruction *instruction) { abi::instruction::Suffix suffix = instruction->suffix(); if (suffix == abi::instruction::RICI or suffix == abi::instruction::RRI or suffix == abi::instruction::RRIC or suffix == abi::instruction::RRICI or suffix == abi::instruction::RRIF or suffix == abi::instruction::ZRI or suffix == abi::instruction::ZRIC or suffix == abi::instruction::ZRICI or suffix == abi::instruction::ZRIF or suffix == abi::instruction::S_RRI or suffix == abi::instruction::U_RRI or suffix == abi::instruction::S_RRIC or suffix == abi::instruction::U_RRIC or suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRICI or suffix == abi::instruction::S_RRIF or suffix == abi::instruction::U_RRIF or suffix == abi::instruction::RR or suffix == abi::instruction::RRC or suffix == abi::instruction::RRCI or suffix == abi::instruction::ZR or suffix == abi::instruction::ZRC or suffix == abi::instruction::ZRCI or suffix == abi::instruction::S_RR or suffix == abi::instruction::U_RR or suffix == abi::instruction::S_RRC or suffix == abi::instruction::U_RRC or suffix == abi::instruction::S_RRCI or suffix == abi::instruction::U_RRCI or suffix == abi::instruction::RIR or suffix == abi::instruction::RIRC or suffix == abi::instruction::RIRCI or suffix == abi::instruction::ZIR or suffix == abi::instruction::ZIRC or suffix == abi::instruction::ZIRCI or suffix == abi::instruction::S_RIRC or suffix == abi::instruction::U_RIRC or suffix == abi::instruction::S_RIRCI or suffix == abi::instruction::U_RIRCI or suffix == abi::instruction::ERRI or suffix == abi::instruction::S_ERRI or suffix == abi::instruction::U_ERRI or suffix == abi::instruction::EDRI or suffix == abi::instruction::ERII) { if (instruction->ra()->is_gp_reg()) { return {new abi::reg::GPReg(instruction->ra()->gp_reg()->index())}; } else { return {}; } } else if (suffix == abi::instruction::RRR or suffix == abi::instruction::RRRC or suffix == abi::instruction::RRRCI or suffix == abi::instruction::ZRR or suffix == abi::instruction::ZRRC or suffix == abi::instruction::ZRRCI or suffix == abi::instruction::S_RRR or suffix == abi::instruction::U_RRR or suffix == abi::instruction::S_RRRC or suffix == abi::instruction::U_RRRC or suffix == abi::instruction::S_RRRCI or suffix == abi::instruction::U_RRRCI or suffix == abi::instruction::RRRI or suffix == abi::instruction::RRRICI or suffix == abi::instruction::ZRRI or suffix == abi::instruction::ZRRICI or suffix == abi::instruction::S_RRRI or suffix == abi::instruction::U_RRRI or suffix == abi::instruction::S_RRRICI or suffix == abi::instruction::U_RRRICI or suffix == abi::instruction::ERIR or suffix == abi::instruction::DMA_RRI) { if (instruction->ra()->is_gp_reg() and instruction->rb()->is_gp_reg()) { return {new abi::reg::GPReg(instruction->ra()->gp_reg()->index()), new abi::reg::GPReg(instruction->rb()->gp_reg()->index())}; } else if (instruction->ra()->is_gp_reg()) { return {new abi::reg::GPReg(instruction->ra()->gp_reg()->index())}; } else if (instruction->rb()->is_gp_reg()) { return {new abi::reg::GPReg(instruction->rb()->gp_reg()->index())}; } else { return {}; } } else if (suffix == abi::instruction::DRDICI or suffix == abi::instruction::ERID) { if (instruction->ra()->is_gp_reg()) { return {new abi::reg::GPReg(instruction->ra()->gp_reg()->index()), new abi::reg::GPReg(instruction->db()->even_reg()->index()), new abi::reg::GPReg(instruction->db()->odd_reg()->index())}; } else { return {new abi::reg::GPReg(instruction->db()->even_reg()->index()), new abi::reg::GPReg(instruction->db()->odd_reg()->index())}; } } else if (suffix == abi::instruction::R or suffix == abi::instruction::RCI or suffix == abi::instruction::Z or suffix == abi::instruction::ZCI or suffix == abi::instruction::S_R or suffix == abi::instruction::U_R or suffix == abi::instruction::S_RCI or suffix == abi::instruction::U_RCI or suffix == abi::instruction::CI or suffix == abi::instruction::I) { return {}; } else if (suffix == abi::instruction::DDCI) { return {new abi::reg::GPReg(instruction->db()->even_reg()->index()), new abi::reg::GPReg(instruction->db()->odd_reg()->index())}; } else { throw std::invalid_argument(""); } } std::set CycleRule::collect_write_gp_regs( abi::instruction::Instruction *instruction) { abi::instruction::Suffix suffix = instruction->suffix(); if (suffix == abi::instruction::RICI or suffix == abi::instruction::ZRI or suffix == abi::instruction::ZRIC or suffix == abi::instruction::ZRICI or suffix == abi::instruction::ZRIF or suffix == abi::instruction::ZRR or suffix == abi::instruction::ZRRC or suffix == abi::instruction::ZRRCI or suffix == abi::instruction::ZR or suffix == abi::instruction::ZRC or suffix == abi::instruction::ZRCI or suffix == abi::instruction::ZRRI or suffix == abi::instruction::ZRRICI or suffix == abi::instruction::ZIR or suffix == abi::instruction::ZIRC or suffix == abi::instruction::ZIRCI or suffix == abi::instruction::Z or suffix == abi::instruction::ZCI or suffix == abi::instruction::CI or suffix == abi::instruction::I or suffix == abi::instruction::ERII or suffix == abi::instruction::ERIR or suffix == abi::instruction::ERID or suffix == abi::instruction::DMA_RRI) { return {}; } else if (suffix == abi::instruction::RRI or suffix == abi::instruction::RRIC or suffix == abi::instruction::RRICI or suffix == abi::instruction::RRIF or suffix == abi::instruction::RRR or suffix == abi::instruction::RRRC or suffix == abi::instruction::RRRCI or suffix == abi::instruction::RR or suffix == abi::instruction::RRC or suffix == abi::instruction::RRCI or suffix == abi::instruction::RRRI or suffix == abi::instruction::RRRICI or suffix == abi::instruction::RIR or suffix == abi::instruction::RIRC or suffix == abi::instruction::RIRCI or suffix == abi::instruction::R or suffix == abi::instruction::RCI or suffix == abi::instruction::ERRI) { return {new abi::reg::GPReg(instruction->rc()->index())}; } else if (suffix == abi::instruction::S_RRI or suffix == abi::instruction::U_RRI or suffix == abi::instruction::S_RRIC or suffix == abi::instruction::U_RRIC or suffix == abi::instruction::S_RRICI or suffix == abi::instruction::U_RRICI or suffix == abi::instruction::S_RRIF or suffix == abi::instruction::U_RRIF or suffix == abi::instruction::S_RRR or suffix == abi::instruction::U_RRR or suffix == abi::instruction::S_RRRC or suffix == abi::instruction::U_RRRC or suffix == abi::instruction::S_RRRCI or suffix == abi::instruction::U_RRRCI or suffix == abi::instruction::S_RR or suffix == abi::instruction::U_RR or suffix == abi::instruction::S_RRC or suffix == abi::instruction::U_RRC or suffix == abi::instruction::S_RRCI or suffix == abi::instruction::U_RRCI or suffix == abi::instruction::DRDICI or suffix == abi::instruction::S_RRRI or suffix == abi::instruction::U_RRRI or suffix == abi::instruction::S_RRRICI or suffix == abi::instruction::U_RRRICI or suffix == abi::instruction::S_RIRC or suffix == abi::instruction::U_RIRC or suffix == abi::instruction::S_RIRCI or suffix == abi::instruction::U_RIRCI or suffix == abi::instruction::S_R or suffix == abi::instruction::U_R or suffix == abi::instruction::DDCI or suffix == abi::instruction::S_ERRI or suffix == abi::instruction::U_ERRI or suffix == abi::instruction::EDRI) { return {new abi::reg::GPReg(instruction->dc()->even_reg()->index()), new abi::reg::GPReg(instruction->dc()->odd_reg()->index())}; } else { throw std::invalid_argument(""); } } std::set CycleRule::merge( std::set regs1, std::set regs2) { std::set regs; auto finder = [®s](RegIndex index) { for (auto ® : regs) { if (reg->index() == index) { return true; } } return false; }; for (auto ® : regs1) { if (not finder(reg->index())) { regs.insert(reg); } } for (auto ® : regs2) { if (not finder(reg->index())) { regs.insert(reg); } } return std::move(regs); } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/cycle_rule.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_CYCLE_RULE_H_ #define UPMEM_SIM_SIMULATOR_DPU_CYCLE_RULE_H_ #include "abi/instruction/instruction.h" #include "simulator/basic/queue.h" #include "simulator/basic/timer_queue.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dpu { class CycleRule { public: explicit CycleRule(util::ArgumentParser *argument_parser); ~CycleRule(); util::StatFactory *stat_factory(); bool empty() { return input_q_->empty() and wait_q_->empty() and ready_q_->empty(); } bool can_push() { return input_q_->can_push(); } void push(abi::instruction::Instruction *instruction); bool can_pop() { return ready_q_->can_pop(); } abi::instruction::Instruction *pop() { return ready_q_->pop(); } void cycle(); protected: void service_input_q(); void service_ready_q(); int calculate_extra_cycles(abi::instruction::Instruction *instruction); std::tuple calculate_counters( abi::instruction::Instruction *instruction); static std::set collect_read_gp_regs( abi::instruction::Instruction *instruction); static std::set collect_write_gp_regs( abi::instruction::Instruction *instruction); static std::set merge(std::set regs1, std::set regs2); private: basic::Queue *input_q_; basic::TimerQueue *wait_q_; basic::Queue *ready_q_; std::vector> prev_write_gp_regs_; std::vector> cur_read_gp_regs_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dma.cc ================================================ #include "simulator/dpu/dma.h" namespace upmem_sim::simulator::dpu { DMA::~DMA() { delete input_q_; delete ready_q_; } void DMA::connect_atomic(sram::Atomic *atomic) { assert(atomic != nullptr); assert(atomic_ == nullptr); atomic_ = atomic; } void DMA::connect_iram(sram::IRAM *iram) { assert(iram != nullptr); assert(iram_ == nullptr); iram_ = iram; } void DMA::connect_operand_collector(OperandCollector *operand_collector) { assert(operand_collector != nullptr); assert(operand_collector_ == nullptr); operand_collector_ = operand_collector; } void DMA::connect_memory_controller(dram::MemoryController *memory_controller) { assert(memory_controller != nullptr); assert(memory_controller_ == nullptr); memory_controller_ = memory_controller; } void DMA::transfer_to_atomic(Address address, encoder::ByteStream *byte_stream) { for (int i = 0; i < byte_stream->size(); i++) { assert(byte_stream->byte(i) == 0); } } void DMA::transfer_to_iram(Address address, encoder::ByteStream *byte_stream) { assert(address == iram_->address()); assert(byte_stream->size() % abi::word::InstructionWord().size() == 0); int num_instructions = static_cast(byte_stream->size() / abi::word::InstructionWord().size()); for (int i = 0; i < num_instructions; i++) { Address begin = i * abi::word::InstructionWord().size(); Address end = (i + 1) * abi::word::InstructionWord().size(); encoder::ByteStream *instruction_byte_stream = byte_stream->slice(static_cast(begin), static_cast(end)); iram_->write(util::ConfigLoader::iram_offset() + begin, instruction_byte_stream); delete instruction_byte_stream; } } encoder::ByteStream *DMA::transfer_from_wram(Address address, Address size) { auto byte_stream = new encoder::ByteStream(); for (int i = 0; i < size; i++) { byte_stream->append(static_cast(operand_collector_->lbu(address + i))); } return byte_stream; } void DMA::transfer_to_wram(Address address, encoder::ByteStream *byte_stream) { for (int i = 0; i < byte_stream->size(); i++) { operand_collector_->sb(address + i, byte_stream->byte(i)); } } encoder::ByteStream *DMA::transfer_from_mram(Address address, Address size) { memory_controller_->flush(); std::vector bytes = memory_controller_->read(address, size); return new encoder::ByteStream(bytes); } void DMA::transfer_to_mram(Address address, encoder::ByteStream *byte_stream) { memory_controller_->write(address, byte_stream->size(), byte_stream); } void DMA::transfer_from_wram_to_mram( Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction) { assert(can_push()); encoder::ByteStream *byte_stream = transfer_from_wram(wram_address, size); std::vector bytes = byte_stream->bytes(); delete byte_stream; auto dma_command = new DMACommand(DMACommand::WRITE, wram_address, mram_address, size, bytes, instruction); input_q_->push(dma_command); } void DMA::transfer_from_mram_to_wram( Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction) { assert(can_push()); auto dma_command = new DMACommand(DMACommand::READ, wram_address, mram_address, size, instruction); input_q_->push(dma_command); } void DMA::cycle() { service_input_q(); service_ready_q(); } void DMA::service_input_q() { if (input_q_->can_pop() and memory_controller_->can_push()) { DMACommand *dma_command = input_q_->pop(); memory_controller_->push(dma_command); } } void DMA::service_ready_q() { if (memory_controller_->can_pop() and ready_q_->can_push()) { DMACommand *dma_command = memory_controller_->pop(); ready_q_->push(dma_command); if (dma_command->operation() == DMACommand::READ) { auto byte_stream = new encoder::ByteStream(dma_command->bytes()); transfer_to_wram(dma_command->wram_address(), byte_stream); delete byte_stream; } } } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dma.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_DMA_H_ #define UPMEM_SIM_SIMULATOR_DPU_DMA_H_ #include "simulator/dpu/operand_collector.h" #include "simulator/dram/memory_controller.h" #include "simulator/sram/atomic.h" #include "simulator/sram/iram.h" #include "simulator/sram/wram.h" namespace upmem_sim::simulator::dpu { class DMA { public: explicit DMA() : atomic_(nullptr), iram_(nullptr), operand_collector_(nullptr), memory_controller_(nullptr), input_q_(new basic::Queue( util::ConfigLoader::max_num_tasklets())), ready_q_(new basic::Queue( util::ConfigLoader::max_num_tasklets())) {} ~DMA(); void connect_atomic(sram::Atomic *atomic); void connect_iram(sram::IRAM *iram); void connect_operand_collector(OperandCollector *operand_collector); void connect_memory_controller(dram::MemoryController *memory_controller); void transfer_to_atomic(Address address, encoder::ByteStream *byte_stream); void transfer_to_iram(Address address, encoder::ByteStream *byte_stream); encoder::ByteStream *transfer_from_wram(Address address, Address size); void transfer_to_wram(Address address, encoder::ByteStream *byte_stream); encoder::ByteStream *transfer_from_mram(Address address, Address size); void transfer_to_mram(Address address, encoder::ByteStream *byte_stream); void transfer_from_wram_to_mram(Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction); void transfer_from_mram_to_wram(Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction); bool can_push() { return input_q_->can_push(); } void push(DMACommand *dma_command) = delete; bool can_pop() { return ready_q_->can_pop(); } DMACommand *pop() { return ready_q_->pop(); } void cycle(); protected: void service_input_q(); void service_ready_q(); private: sram::Atomic *atomic_; sram::IRAM *iram_; OperandCollector *operand_collector_; dram::MemoryController *memory_controller_; basic::Queue *input_q_; basic::Queue *ready_q_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dma_command.cc ================================================ #include "simulator/dpu/dma_command.h" #include #include "abi/word/data_word.h" namespace upmem_sim::simulator::dpu { DMACommand::DMACommand(Operation operation, Address mram_address, Address size) : operation_(operation), wram_address_(nullptr), mram_address_(new abi::word::DataAddressWord()), size_(size), instruction_(nullptr) { assert(operation == READ); assert(mram_address >= util::ConfigLoader::mram_offset()); assert(mram_address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(size % util::ConfigLoader::min_access_granularity() == 0); mram_address_->set_value(mram_address); bytes_.resize(size); acks_.resize(size); } DMACommand::DMACommand(Operation operation, Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction) : operation_(operation), wram_address_(new abi::word::DataAddressWord()), mram_address_(new abi::word::DataAddressWord()), size_(size), instruction_(instruction) { assert(operation == READ); assert(wram_address >= util::ConfigLoader::wram_offset()); assert(wram_address + size_ <= util::ConfigLoader::wram_offset() + util::ConfigLoader::wram_size()); assert(mram_address >= util::ConfigLoader::mram_offset()); assert(mram_address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(size % util::ConfigLoader::min_access_granularity() == 0); assert(instruction->op_code() == abi::instruction::LDMA); wram_address_->set_value(wram_address); mram_address_->set_value(mram_address); bytes_.resize(size); acks_.resize(size); } DMACommand::DMACommand(Operation operation, Address mram_address, Address size, std::vector bytes) : operation_(operation), wram_address_(nullptr), mram_address_(new abi::word::DataAddressWord()), size_(size), bytes_(bytes), instruction_(nullptr) { assert(operation == WRITE); assert(mram_address >= util::ConfigLoader::mram_offset()); assert(mram_address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(size % util::ConfigLoader::min_access_granularity() == 0); assert(size == bytes.size()); mram_address_->set_value(mram_address); bytes_.resize(size); acks_.resize(size); } DMACommand::DMACommand(Operation operation, Address wram_address, Address mram_address, Address size, std::vector bytes, abi::instruction::Instruction *instruction) : operation_(operation), wram_address_(new abi::word::DataAddressWord()), mram_address_(new abi::word::DataAddressWord()), size_(size), bytes_(bytes), instruction_(instruction) { assert(operation == WRITE); assert(wram_address >= util::ConfigLoader::wram_offset()); assert(wram_address + size_ <= util::ConfigLoader::wram_offset() + util::ConfigLoader::wram_size()); assert(mram_address >= util::ConfigLoader::mram_offset()); assert(mram_address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(size % util::ConfigLoader::min_access_granularity() == 0); assert(size == bytes.size()); assert(instruction->op_code() == abi::instruction::SDMA); wram_address_->set_value(wram_address); mram_address_->set_value(mram_address); bytes_.resize(size); acks_.resize(size); } DMACommand::~DMACommand() { assert(is_ready()); delete wram_address_; delete mram_address_; } abi::instruction::Instruction *DMACommand::instruction() { assert(has_instruction()); return instruction_; } std::vector DMACommand::bytes() { if (operation_ == READ) { assert(is_ready()); } return bytes_; } std::vector DMACommand::bytes(Address mram_address, Address size) { std::vector bytes; bytes.resize(size); std::copy(bytes_.begin() + index(mram_address), bytes_.begin() + index(mram_address) + size, bytes.begin()); return std::move(bytes); } void DMACommand::set_bytes(Address mram_address, Address size, std::vector bytes) { assert(size == bytes.size()); std::copy(bytes.begin(), bytes.end(), bytes_.begin() + index(mram_address)); } void DMACommand::ack_bytes(Address mram_address, Address size) { for (int i = 0; i < size; i++) { assert(not acks_[index(mram_address) + i]); acks_[index(mram_address) + i] = true; } } int DMACommand::index(Address mram_address) { assert(this->mram_address() <= mram_address and mram_address <= this->mram_address() + size_); return static_cast(mram_address - this->mram_address()); } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dma_command.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_DMA_COMMAND_H_ #define UPMEM_SIM_SIMULATOR_DPU_DMA_COMMAND_H_ #include #include "abi/instruction/instruction.h" #include "abi/word/data_address_word.h" #include "abi/word/data_word.h" #include "main.h" namespace upmem_sim::simulator::dpu { class DMACommand { public: enum Operation { READ = 0, WRITE }; explicit DMACommand(Operation operation, Address mram_address, Address size); explicit DMACommand(Operation operation, Address wram_address, Address mram_address, Address size, abi::instruction::Instruction *instruction); explicit DMACommand(Operation operation, Address mram_address, Address size, std::vector bytes); explicit DMACommand(Operation operation, Address wram_address, Address mram_address, Address size, std::vector bytes, abi::instruction::Instruction *instruction); ~DMACommand(); Operation operation() { return operation_; } Address wram_address() { return wram_address_->address(); } Address mram_address() { return mram_address_->address(); } Address size() { return size_; } bool has_instruction() { return instruction_ != nullptr; } abi::instruction::Instruction *instruction(); std::vector bytes(); std::vector bytes(Address mram_address, Address size); void set_bytes(Address mram_address, Address size, std::vector bytes); void ack_bytes(Address mram_address, Address size); bool is_ready() { return std::all_of(acks_.begin(), acks_.end(), [](bool ack) { return ack; }); } protected: int index(Address mram_address); private: Operation operation_; abi::word::DataAddressWord *wram_address_; abi::word::DataAddressWord *mram_address_; Address size_; abi::instruction::Instruction *instruction_; std::vector bytes_; std::vector acks_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dpu.cc ================================================ #include "simulator/dpu/dpu.h" #include #include namespace upmem_sim::simulator::dpu { DPU::DPU(DPUID dpu_id, util::ArgumentParser *argument_parser) : dpu_id_(dpu_id), atomic_(new sram::Atomic()), iram_(new sram::IRAM()), wram_(new sram::WRAM()), mram_(new dram::MRAM(argument_parser)), logic_(new Logic(dpu_id, argument_parser)), dma_(new DMA()), operand_collector_(new OperandCollector()), memory_controller_(new dram::MemoryController(argument_parser)), stat_factory_(new util::StatFactory("DPU#" + std::to_string(dpu_id))) { int num_threads = static_cast(argument_parser->get_int_parameter("num_tasklets")); assert(0 <= num_threads and num_threads <= util::ConfigLoader::max_num_tasklets()); threads_.resize(num_threads); for (ThreadID id = 0; id < num_threads; id++) { threads_[id] = new Thread(id); } scheduler_ = new RevolverScheduler(argument_parser, threads_); logic_->connect_scheduler(scheduler_); logic_->connect_atomic(atomic_); logic_->connect_iram(iram_); logic_->connect_operand_collector(operand_collector_); logic_->connect_dma(dma_); dma_->connect_atomic(atomic_); dma_->connect_iram(iram_); dma_->connect_operand_collector(operand_collector_); dma_->connect_memory_controller(memory_controller_); operand_collector_->connect_wram(wram_); memory_controller_->connect_mram(mram_); logic_frequency_ = static_cast(argument_parser->get_int_parameter("logic_frequency")); memory_frequency_ = static_cast(argument_parser->get_int_parameter("memory_frequency")); frequency_ratio_ = static_cast(memory_frequency_) / static_cast(logic_frequency_); } DPU::~DPU() { for (auto &thread : threads_) { delete thread; } delete scheduler_; delete atomic_; delete iram_; delete wram_; delete mram_; delete logic_; delete dma_; delete operand_collector_; delete memory_controller_; delete stat_factory_; } util::StatFactory *DPU::stat_factory() { auto stat_factory = new util::StatFactory(""); util::StatFactory *logic_stat_factory = logic_->stat_factory(); util::StatFactory *memory_stat_factory = memory_controller_->stat_factory(); for (auto &thread : threads_) { std::map status_tracker = thread->status_tracker(); for (const auto &stat : status_tracker) { stat_factory_->increment( std::to_string(thread->id()) + "_latency_breakdown_" + stat.first, stat.second); } } stat_factory->merge(stat_factory_); stat_factory->merge(logic_stat_factory); stat_factory->merge(memory_stat_factory); delete logic_stat_factory; delete memory_stat_factory; return stat_factory; } bool DPU::is_zombie() { for (auto &thread : threads_) { if (thread->state() != Thread::ZOMBIE) { return false; } } return logic_->empty() and memory_controller_->empty(); } void DPU::cycle() { scheduler_->cycle(); logic_->cycle(); dma_->cycle(); int num_memory_cycles = static_cast( floor(frequency_ratio_ * static_cast(stat_factory_->value("cycle"))) - floor(frequency_ratio_ * static_cast(stat_factory_->value("cycle") - 1))); for (int i = 0; i < num_memory_cycles; i++) { memory_controller_->cycle(); } stat_factory_->increment("cycle"); } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/dpu.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_DPU_H_ #define UPMEM_SIM_SIMULATOR_DPU_DPU_H_ #include "simulator/dpu/dma.h" #include "simulator/dpu/logic.h" #include "simulator/dpu/operand_collector.h" #include "simulator/dram/memory_controller.h" #include "simulator/dram/mram.h" #include "simulator/sram/atomic.h" #include "simulator/sram/iram.h" #include "simulator/sram/wram.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dpu { class DPU { public: explicit DPU(DPUID dpu_id, util::ArgumentParser *argument_parser); ~DPU(); DPUID dpu_id() { return dpu_id_; } RevolverScheduler *scheduler() { return scheduler_; } DMA *dma() { return dma_; } util::StatFactory *stat_factory(); bool is_zombie(); void boot() { scheduler_->boot(0); } void cycle(); private: DPUID dpu_id_; std::vector threads_; RevolverScheduler *scheduler_; sram::Atomic *atomic_; sram::IRAM *iram_; sram::WRAM *wram_; dram::MRAM *mram_; Logic *logic_; DMA *dma_; OperandCollector *operand_collector_; dram::MemoryController *memory_controller_; int logic_frequency_; int memory_frequency_; double frequency_ratio_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/logic.cc ================================================ #include "simulator/dpu/logic.h" #include #include #include #include "converter/instruction_converter.h" #include "converter/reg_file_converter.h" #include "simulator/dpu/alu.h" namespace upmem_sim::simulator::dpu { Logic::~Logic() { delete pipeline_; delete cycle_rule_; delete wait_instruction_q_; delete stat_factory_; } util::StatFactory *Logic::stat_factory() { auto stat_factory = new util::StatFactory(""); util::StatFactory *cycle_rule_stat_factory = cycle_rule_->stat_factory(); util::StatFactory *scheduler_stat_factory = scheduler_->stat_factory(); stat_factory->merge(stat_factory_); stat_factory->merge(cycle_rule_stat_factory); stat_factory->merge(scheduler_stat_factory); delete cycle_rule_stat_factory; delete scheduler_stat_factory; return stat_factory; } void Logic::connect_scheduler(RevolverScheduler *scheduler) { assert(scheduler != nullptr); assert(scheduler_ == nullptr); scheduler_ = scheduler; } void Logic::connect_atomic(sram::Atomic *atomic) { assert(atomic != nullptr); assert(atomic_ == nullptr); atomic_ = atomic; } void Logic::connect_iram(sram::IRAM *iram) { assert(iram != nullptr); assert(iram_ == nullptr); iram_ = iram; } void Logic::connect_operand_collector(OperandCollector *operand_collector) { assert(operand_collector != nullptr); assert(operand_collector_ == nullptr); operand_collector_ = operand_collector; } void Logic::connect_dma(DMA *dma) { assert(dma != nullptr); assert(dma_ == nullptr); dma_ = dma; } void Logic::cycle() { stat_factory_->overwrite("mram_address", -1); stat_factory_->overwrite("mram_access_thread", -1); stat_factory_->overwrite("mram_access_size", -1); service_scheduler(); service_pipeline(); service_cycle_rule(); service_logic(); service_dma(); pipeline_->cycle(); cycle_rule_->cycle(); stat_factory_->increment("logic_cycle"); } void Logic::service_scheduler() { if (pipeline_->can_push() and cycle_rule_->can_push() and wait_instruction_q_->can_push()) { // if (pipeline_->can_push() and wait_instruction_q_->can_push()) { Thread *thread = scheduler_->schedule(); if (thread != nullptr) { int chosen_thread_id = thread->id(); abi::instruction::Instruction *instruction = iram_->read(thread->reg_file()->read_pc_reg()); instruction->set_thread(thread); pipeline_->push(instruction); if (instruction->suffix() != abi::instruction::DMA_RRI) { if (verbose_ >= 1) { std::cout << "{" << dpu_id_ << "}"; std::cout << converter::InstructionConverter::to_string(instruction) << std::endl; } execute_instruction(instruction); if (verbose_ >= 2) { std::cout << converter::RegFileConverter::to_string(instruction->thread()->reg_file()) << std::endl; } } else { scheduler_->block(thread->id()); instruction->thread()->reg_file()->increment_pc_reg(); wait_instruction_q_->push(instruction); } stat_factory_->increment("num_instructions"); stat_factory_->increment(std::to_string(instruction->thread()->id()) + "_num_instructions"); for (auto &th : scheduler_->threads()) { if (th->state() == Thread::BLOCK) { th->update_thread_status("WAIT_DATA", 1); } else if (th->state() == Thread::RUNNABLE and chosen_thread_id != th->id()) { th->update_thread_status("WAIT_SCHEDULE", 1); } } } else { for (auto &th : scheduler_->threads()) { if (th->state() == Thread::BLOCK) { th->update_thread_status("WAIT_DATA", 1); } } } stat_factory_->increment("active_tasklets_" + std::to_string(scheduler_->get_issuable_threads())); } else { stat_factory_->increment("backpressuer"); stat_factory_->increment("active_tasklets_" + std::to_string(0)); } } void Logic::service_pipeline() { if (pipeline_->can_pop() and cycle_rule_->can_push()) { abi::instruction::Instruction *instruction = pipeline_->pop(); if (instruction != nullptr) { abi::instruction::Suffix suffix = instruction->suffix(); if (suffix == abi::instruction::ERRI or suffix == abi::instruction::EDRI or suffix == abi::instruction::ERII or suffix == abi::instruction::ERIR or suffix == abi::instruction::ERID) { // spm access instruction->thread()->update_thread_status("SPM_ACCESS", num_pipeline_stages_); } else if (suffix == abi::instruction::RICI) { // sync instruction->thread()->update_thread_status("WAIT_SYNC", num_pipeline_stages_); } else if (suffix != abi::instruction::DMA_RRI) { instruction->thread()->update_thread_status("ARITHMETIC", num_pipeline_stages_); } cycle_rule_->push(instruction); } } } void Logic::service_cycle_rule() { if (cycle_rule_->can_pop()) { abi::instruction::Instruction *instruction = cycle_rule_->pop(); if (instruction->suffix() != abi::instruction::DMA_RRI) { delete instruction; } else { if (verbose_ >= 1) { std::cout << "{" << dpu_id_ << "}"; std::cout << converter::InstructionConverter::to_string(instruction) << std::endl; } execute_instruction(instruction); if (verbose_ >= 2) { std::cout << converter::RegFileConverter::to_string(instruction->thread()->reg_file()) << std::endl; } } } } void Logic::service_logic() {} void Logic::service_dma() { if (wait_instruction_q_->can_pop() and dma_->can_pop()) { DMACommand *dma_command = dma_->pop(); abi::instruction::Instruction *instruction = wait_instruction_q_->pop(); assert(dma_command->instruction() == instruction); scheduler_->awake(instruction->thread()->id()); delete dma_command; delete instruction; } } void Logic::execute_instruction(abi::instruction::Instruction *instruction) { abi::instruction::Suffix suffix = instruction->suffix(); if (suffix == abi::instruction::RICI) { execute_rici(instruction); } else if (suffix == abi::instruction::RRI) { execute_rri(instruction); } else if (suffix == abi::instruction::RRIC) { execute_rric(instruction); } else if (suffix == abi::instruction::RRICI) { execute_rrici(instruction); } else if (suffix == abi::instruction::RRIF) { execute_rrif(instruction); } else if (suffix == abi::instruction::RRR) { execute_rrr(instruction); } else if (suffix == abi::instruction::RRRC) { execute_rrrc(instruction); } else if (suffix == abi::instruction::RRRCI) { execute_rrrci(instruction); } else if (suffix == abi::instruction::ZRI) { execute_zri(instruction); } else if (suffix == abi::instruction::ZRIC) { execute_zric(instruction); } else if (suffix == abi::instruction::ZRICI) { execute_zrici(instruction); } else if (suffix == abi::instruction::ZRIF) { execute_zrif(instruction); } else if (suffix == abi::instruction::ZRR) { execute_zrr(instruction); } else if (suffix == abi::instruction::ZRRC) { execute_zrrc(instruction); } else if (suffix == abi::instruction::ZRRCI) { execute_zrrci(instruction); } else if (suffix == abi::instruction::S_RRI) { execute_s_rri(instruction); } else if (suffix == abi::instruction::S_RRIC) { execute_s_rric(instruction); } else if (suffix == abi::instruction::S_RRICI) { execute_s_rrici(instruction); } else if (suffix == abi::instruction::S_RRIF) { execute_s_rrif(instruction); } else if (suffix == abi::instruction::S_RRR) { execute_s_rrr(instruction); } else if (suffix == abi::instruction::S_RRRC) { execute_s_rrrc(instruction); } else if (suffix == abi::instruction::S_RRRCI) { execute_s_rrrci(instruction); } else if (suffix == abi::instruction::U_RRI) { execute_u_rri(instruction); } else if (suffix == abi::instruction::U_RRIC) { execute_u_rric(instruction); } else if (suffix == abi::instruction::U_RRICI) { execute_u_rrici(instruction); } else if (suffix == abi::instruction::U_RRIF) { execute_u_rrif(instruction); } else if (suffix == abi::instruction::U_RRR) { execute_u_rrr(instruction); } else if (suffix == abi::instruction::U_RRRC) { execute_u_rrrc(instruction); } else if (suffix == abi::instruction::U_RRRCI) { execute_u_rrrci(instruction); } else if (suffix == abi::instruction::RR) { execute_rr(instruction); } else if (suffix == abi::instruction::RRC) { execute_rrc(instruction); } else if (suffix == abi::instruction::RRCI) { execute_rrci(instruction); } else if (suffix == abi::instruction::ZR) { execute_zr(instruction); } else if (suffix == abi::instruction::ZRC) { execute_zrc(instruction); } else if (suffix == abi::instruction::ZRCI) { execute_zrci(instruction); } else if (suffix == abi::instruction::S_RR) { execute_s_rr(instruction); } else if (suffix == abi::instruction::S_RRC) { execute_s_rrc(instruction); } else if (suffix == abi::instruction::S_RRCI) { execute_s_rrci(instruction); } else if (suffix == abi::instruction::U_RR) { execute_u_rr(instruction); } else if (suffix == abi::instruction::U_RRC) { execute_u_rrc(instruction); } else if (suffix == abi::instruction::U_RRCI) { execute_u_rrci(instruction); } else if (suffix == abi::instruction::DRDICI) { execute_drdici(instruction); } else if (suffix == abi::instruction::RRRI) { execute_rrri(instruction); } else if (suffix == abi::instruction::RRRICI) { execute_rrrici(instruction); } else if (suffix == abi::instruction::ZRRI) { execute_zrri(instruction); } else if (suffix == abi::instruction::ZRRICI) { execute_zrrici(instruction); } else if (suffix == abi::instruction::S_RRRI) { execute_s_rrri(instruction); } else if (suffix == abi::instruction::S_RRRICI) { execute_s_rrrici(instruction); } else if (suffix == abi::instruction::U_RRRI) { execute_u_rrri(instruction); } else if (suffix == abi::instruction::U_RRRICI) { execute_u_rrrici(instruction); } else if (suffix == abi::instruction::RIR) { execute_rir(instruction); } else if (suffix == abi::instruction::RIRC) { execute_rirc(instruction); } else if (suffix == abi::instruction::RIRCI) { execute_rirci(instruction); } else if (suffix == abi::instruction::ZIR) { execute_zir(instruction); } else if (suffix == abi::instruction::ZIRC) { execute_zirc(instruction); } else if (suffix == abi::instruction::ZIRCI) { execute_zirci(instruction); } else if (suffix == abi::instruction::S_RIRC) { execute_s_rirc(instruction); } else if (suffix == abi::instruction::S_RIRCI) { execute_s_rirci(instruction); } else if (suffix == abi::instruction::U_RIRC) { execute_u_rirc(instruction); } else if (suffix == abi::instruction::U_RIRCI) { execute_u_rirci(instruction); } else if (suffix == abi::instruction::R) { execute_r(instruction); } else if (suffix == abi::instruction::RCI) { execute_rci(instruction); } else if (suffix == abi::instruction::Z) { execute_z(instruction); } else if (suffix == abi::instruction::ZCI) { execute_zci(instruction); } else if (suffix == abi::instruction::S_R) { execute_s_r(instruction); } else if (suffix == abi::instruction::S_RCI) { execute_s_rci(instruction); } else if (suffix == abi::instruction::U_R) { execute_u_r(instruction); } else if (suffix == abi::instruction::U_RCI) { execute_u_rci(instruction); } else if (suffix == abi::instruction::CI) { execute_ci(instruction); } else if (suffix == abi::instruction::I) { execute_i(instruction); } else if (suffix == abi::instruction::DDCI) { execute_ddci(instruction); } else if (suffix == abi::instruction::ERRI) { execute_erri(instruction); } else if (suffix == abi::instruction::S_ERRI) { execute_s_erri(instruction); } else if (suffix == abi::instruction::U_ERRI) { execute_u_erri(instruction); } else if (suffix == abi::instruction::EDRI) { execute_edri(instruction); } else if (suffix == abi::instruction::ERII) { execute_erii(instruction); } else if (suffix == abi::instruction::ERIR) { execute_erir(instruction); } else if (suffix == abi::instruction::ERID) { execute_erid(instruction); } else if (suffix == abi::instruction::DMA_RRI) { execute_dma_rri(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_rici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::acquire_rici_op_codes().count(op_code)) { execute_acquire_rici(instruction); } else if (abi::instruction::Instruction::release_rici_op_codes().count( op_code)) { execute_release_rici(instruction); } else if (abi::instruction::Instruction::boot_rici_op_codes().count( op_code)) { execute_boot_rici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_acquire_rici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::acquire_rici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::UNSIGNED); int64_t imm = instruction->imm()->value(); Address atomic_address = ALU::atomic_address_hash(ra, imm); bool can_acquire = atomic_->can_acquire(atomic_address); if (can_acquire) { atomic_->acquire(atomic_address, instruction->thread()->id()); } instruction->thread()->reg_file()->clear_conditions(); set_acquire_cc(instruction, not can_acquire); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, not can_acquire, false); } void Logic::execute_release_rici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::release_rici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::UNSIGNED); int64_t imm = instruction->imm()->value(); Address atomic_address = ALU::atomic_address_hash(ra, imm); bool can_release = atomic_->can_release(atomic_address, instruction->thread()->id()); if (can_release) { atomic_->release(atomic_address, instruction->thread()->id()); } instruction->thread()->reg_file()->clear_conditions(); set_acquire_cc(instruction, not can_release); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, not can_release, false); } void Logic::execute_boot_rici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::boot_rici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::UNSIGNED); int64_t imm = instruction->imm()->value(); Address thread_id = ALU::atomic_address_hash(ra, imm); instruction->thread()->reg_file()->clear_conditions(); abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::BOOT) { bool can_boot = scheduler_->boot(static_cast(thread_id)); set_boot_cc(instruction, ra, not can_boot); set_flags(instruction, not can_boot, false); } else if (op_code == abi::instruction::RESUME) { bool can_resume = scheduler_->awake(static_cast(thread_id)); set_boot_cc(instruction, ra, not can_resume); set_flags(instruction, not can_resume, false); } else { throw std::invalid_argument(""); } if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } } void Logic::execute_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { execute_add_rri(instruction); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { execute_asr_rri(instruction); } else if (abi::instruction::Instruction::call_rri_op_codes().count( op_code)) { execute_call_rri(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_call_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::call_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); Address result; bool carry; bool overflow; if (imm == 0) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else { std::tie(result, carry, overflow) = ALU::add(ra * abi::word::InstructionWord().size(), imm); } instruction->thread()->reg_file()->clear_conditions(); Address pc = instruction->thread()->reg_file()->read_pc_reg(); instruction->thread()->reg_file()->write_gp_reg( instruction->rc(), pc + abi::word::InstructionWord().size()); instruction->thread()->reg_file()->write_pc_reg(result); set_flags(instruction, result, carry); } void Logic::execute_rric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRIC); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rric_op_codes().count(op_code)) { execute_add_rric(instruction); } else if (abi::instruction::Instruction::asr_rric_op_codes().count( op_code)) { execute_asr_rric(instruction); } else if (abi::instruction::Instruction::sub_rric_op_codes().count( op_code)) { execute_sub_rric(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_rric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_rric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_sub_rric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_ext_sub_set_cc(instruction, ra, imm, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code)) { execute_add_rrici(instruction); } else if (abi::instruction::Instruction::and_rrici_op_codes().count( op_code)) { execute_and_rrici(instruction); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { execute_asr_rrici(instruction); } else if (abi::instruction::Instruction::sub_rrici_op_codes().count( op_code)) { execute_sub_rrici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_imm_shift_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_sub_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_rrif(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrif_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRIF); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rrr(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrr_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CALL) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); if (op_code == abi::instruction::CALL) { Address pc = instruction->thread()->reg_file()->read_pc_reg(); instruction->thread()->reg_file()->write_gp_reg( instruction->rc(), pc + abi::word::InstructionWord().size()); instruction->thread()->reg_file()->write_pc_reg(result); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_rrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRC); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrrc_op_codes().count(op_code)) { execute_add_rrrc(instruction); } else if (abi::instruction::Instruction::rsub_rrrc_op_codes().count( op_code)) { execute_rsub_rrrc(instruction); } else if (abi::instruction::Instruction::sub_rrrc_op_codes().count( op_code)) { execute_sub_rrrc(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_rrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rsub_rrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rsub_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_set_cc(instruction, ra, rb, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_sub_rrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_ext_sub_set_cc(instruction, ra, rb, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrrci_op_codes().count(op_code)) { execute_add_rrrci(instruction); } else if (abi::instruction::Instruction::and_rrrci_op_codes().count( op_code)) { execute_and_rrrci(instruction); } else if (abi::instruction::Instruction::asr_rrrci_op_codes().count( op_code)) { execute_asr_rrrci(instruction); } else if (abi::instruction::Instruction::mul_rrrci_op_codes().count( op_code)) { execute_mul_rrrci(instruction); } else if (abi::instruction::Instruction::rsub_rrrci_op_codes().count( op_code)) { execute_rsub_rrrci(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_mul_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::mul_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_mul_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_rsub_rrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rsub_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, rb, result, carry, overflow); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_zri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { execute_add_zri(instruction); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { execute_asr_zri(instruction); } else if (abi::instruction::Instruction::call_rri_op_codes().count( op_code)) { execute_call_zri(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_zri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_zri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_call_zri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::call_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); Address result; bool carry; bool overflow; if (imm == 0) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else { std::tie(result, carry, overflow) = ALU::add(ra * abi::word::InstructionWord().size(), imm); } instruction->thread()->reg_file()->clear_conditions(); Address pc = instruction->thread()->reg_file()->read_pc_reg(); instruction->thread()->reg_file()->write_pc_reg(result); set_flags(instruction, result, carry); } void Logic::execute_zric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRIC); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rric_op_codes().count(op_code)) { execute_add_zric(instruction); } else if (abi::instruction::Instruction::asr_rric_op_codes().count( op_code)) { execute_asr_zric(instruction); } else if (abi::instruction::Instruction::sub_rric_op_codes().count( op_code)) { execute_sub_zric(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_zric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_zric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_sub_zric(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rric_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRIC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_ext_sub_set_cc(instruction, ra, imm, result, carry, overflow); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_zrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code)) { execute_add_zrici(instruction); } else if (abi::instruction::Instruction::and_rrici_op_codes().count( op_code)) { execute_and_zrici(instruction); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { execute_asr_zrici(instruction); } else if (abi::instruction::Instruction::sub_rrici_op_codes().count( op_code)) { execute_sub_zrici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_zrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_zrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_zrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_imm_shift_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_sub_zrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_zrif(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrif_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRIF); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_zrr(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrr_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CALL) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); if (op_code == abi::instruction::CALL) { instruction->thread()->reg_file()->write_pc_reg(result); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_zrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRC); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrrc_op_codes().count(op_code)) { execute_add_zrrc(instruction); } else if (abi::instruction::Instruction::rsub_rrrc_op_codes().count( op_code)) { execute_rsub_zrrc(instruction); } else if (abi::instruction::Instruction::sub_rrrc_op_codes().count( op_code)) { execute_sub_zrrc(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_zrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rsub_zrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rsub_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_set_cc(instruction, ra, rb, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_sub_zrrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_ext_sub_set_cc(instruction, ra, rb, result, carry, overflow); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrrci_op_codes().count(op_code)) { execute_add_zrrci(instruction); } else if (abi::instruction::Instruction::and_rrrci_op_codes().count( op_code)) { execute_and_zrrci(instruction); } else if (abi::instruction::Instruction::asr_rrrci_op_codes().count( op_code)) { execute_asr_zrrci(instruction); } else if (abi::instruction::Instruction::mul_rrrci_op_codes().count( op_code)) { execute_mul_zrrci(instruction); } else if (abi::instruction::Instruction::rsub_rrrci_op_codes().count( op_code)) { execute_rsub_zrrci(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, rb); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, rb); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, rb); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, rb); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, rb); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, rb); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, rb); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, rb); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, rb); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, rb); } else if (op_code == abi::instruction::CMPB4) { result = ALU::cmpb4(ra, rb); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, rb); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, rb); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, rb); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, rb); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, rb); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, rb); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, rb); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, rb); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, rb); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_mul_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::mul_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::MUL_SH_SH) { result = ALU::mul_sh_sh(ra, rb); } else if (op_code == abi::instruction::MUL_SH_SL) { result = ALU::mul_sh_sl(ra, rb); } else if (op_code == abi::instruction::MUL_SH_UH) { result = ALU::mul_sh_uh(ra, rb); } else if (op_code == abi::instruction::MUL_SH_UL) { result = ALU::mul_sh_ul(ra, rb); } else if (op_code == abi::instruction::MUL_SL_SH) { result = ALU::mul_sl_sh(ra, rb); } else if (op_code == abi::instruction::MUL_SL_SL) { result = ALU::mul_sl_sl(ra, rb); } else if (op_code == abi::instruction::MUL_SL_UH) { result = ALU::mul_sl_uh(ra, rb); } else if (op_code == abi::instruction::MUL_SL_UL) { result = ALU::mul_sl_ul(ra, rb); } else if (op_code == abi::instruction::MUL_UH_UH) { result = ALU::mul_uh_uh(ra, rb); } else if (op_code == abi::instruction::MUL_UH_UL) { result = ALU::mul_uh_ul(ra, rb); } else if (op_code == abi::instruction::MUL_UL_UH) { result = ALU::mul_ul_uh(ra, rb); } else if (op_code == abi::instruction::MUL_UL_UL) { result = ALU::mul_ul_ul(ra, rb); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_mul_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_rsub_zrrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rsub_rrrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::RSUB) { std::tie(result, carry, overflow) = ALU::sub(rb, ra); } else if (op_code == abi::instruction::RSUBC) { std::tie(result, carry, overflow) = ALU::subc( rb, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, rb); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, rb, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, rb, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_s_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { execute_add_s_rri(instruction); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { execute_asr_s_rri(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_s_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_s_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_s_rric(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code)) { execute_add_s_rrici(instruction); } else if (abi::instruction::Instruction::and_rrici_op_codes().count( op_code)) { execute_and_s_rrici(instruction); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { execute_asr_s_rrici(instruction); } else if (abi::instruction::Instruction::sub_rrici_op_codes().count( op_code)) { execute_sub_s_rrici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_s_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_s_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_s_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_imm_shift_nz_cc(instruction, ra, result); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_sub_s_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_s_rrif(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrif_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::S_RRIF); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::signed_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_s_rrr(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrrc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rri_op_codes().count(op_code)) { execute_add_u_rri(instruction); } else if (abi::instruction::Instruction::asr_rri_op_codes().count(op_code)) { execute_asr_u_rri(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_u_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_asr_u_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_u_rric(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::add_rrici_op_codes().count(op_code)) { execute_add_u_rrici(instruction); } else if (abi::instruction::Instruction::and_rrici_op_codes().count( op_code)) { execute_and_u_rrici(instruction); } else if (abi::instruction::Instruction::asr_rrici_op_codes().count( op_code)) { execute_asr_u_rrici(instruction); } else if (abi::instruction::Instruction::sub_rrici_op_codes().count( op_code)) { execute_sub_u_rrici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_add_u_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::add_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_add_nz_cc(instruction, ra, result, carry, overflow); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_and_u_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::and_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_asr_u_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::asr_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ASR) { result = ALU::asr(ra, imm); } else if (op_code == abi::instruction::LSL) { result = ALU::lsl(ra, imm); } else if (op_code == abi::instruction::LSL1) { result = ALU::lsl1(ra, imm); } else if (op_code == abi::instruction::LSL1X) { result = ALU::lsl1x(ra, imm); } else if (op_code == abi::instruction::LSLX) { result = ALU::lslx(ra, imm); } else if (op_code == abi::instruction::LSR) { result = ALU::lsr(ra, imm); } else if (op_code == abi::instruction::LSR1) { result = ALU::lsr1(ra, imm); } else if (op_code == abi::instruction::LSR1X) { result = ALU::lsr1x(ra, imm); } else if (op_code == abi::instruction::LSRX) { result = ALU::lsrx(ra, imm); } else if (op_code == abi::instruction::ROL) { result = ALU::rol(ra, imm); } else if (op_code == abi::instruction::ROR) { result = ALU::ror(ra, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_imm_shift_nz_cc(instruction, ra, result); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_sub_u_rrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sub_rrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_u_rrif(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrif_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::U_RRIF); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::ADD) { std::tie(result, carry, overflow) = ALU::add(ra, imm); } else if (op_code == abi::instruction::ADDC) { std::tie(result, carry, overflow) = ALU::addc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::AND) { result = ALU::and_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ANDN) { result = ALU::andn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NAND) { result = ALU::nand(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NOR) { result = ALU::nor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::NXOR) { result = ALU::nxor(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::OR) { result = ALU::or_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::ORN) { result = ALU::orn(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(ra, imm); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( ra, imm, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else if (op_code == abi::instruction::XOR) { result = ALU::xor_(ra, imm); carry = false; overflow = false; } else if (op_code == abi::instruction::HASH) { result = ALU::hash(ra, imm); carry = false; overflow = false; } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); auto [even, odd] = ALU::unsigned_extension(result); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_u_rrr(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrrc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_rr(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rr_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else if (op_code == abi::instruction::TIME_CFG) { throw std::bad_function_call(); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_rrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else if (op_code == abi::instruction::TIME_CFG) { throw std::bad_function_call(); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_rrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRCI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::cao_rrci_op_codes().count(op_code)) { execute_cao_rrci(instruction); } else if (abi::instruction::Instruction::extsb_rrci_op_codes().count( op_code)) { execute_extsb_rrci(instruction); } else if (abi::instruction::Instruction::time_cfg_rrci_op_codes().count( op_code)) { execute_time_cfg_rrci(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_cao_rrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::cao_rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_count_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_extsb_rrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::extsb_rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_time_cfg_rrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_zr(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rr_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else if (op_code == abi::instruction::TIME_CFG) { throw std::bad_function_call(); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_zrc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else if (op_code == abi::instruction::TIME_CFG) { throw std::bad_function_call(); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_set_cc(instruction, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, false); } void Logic::execute_zrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRCI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::cao_rrci_op_codes().count(op_code)) { execute_cao_zrci(instruction); } else if (abi::instruction::Instruction::extsb_rrci_op_codes().count( op_code)) { execute_extsb_zrci(instruction); } else if (abi::instruction::Instruction::time_cfg_rrci_op_codes().count( op_code)) { execute_time_cfg_zrci(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_cao_zrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::cao_rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::CAO) { result = ALU::cao(ra); } else if (op_code == abi::instruction::CLO) { result = ALU::clo(ra); } else if (op_code == abi::instruction::CLS) { result = ALU::cls(ra); } else if (op_code == abi::instruction::CLZ) { result = ALU::clz(ra); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_count_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_extsb_zrci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::extsb_rrci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::EXTSB) { result = ALU::extsb(ra); } else if (op_code == abi::instruction::EXTSH) { result = ALU::extsh(ra); } else if (op_code == abi::instruction::EXTUB) { result = ALU::extub(ra); } else if (op_code == abi::instruction::EXTUH) { result = ALU::extuh(ra); } else if (op_code == abi::instruction::SATS) { result = ALU::sats(ra); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_log_nz_cc(instruction, ra, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); } void Logic::execute_time_cfg_zrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rr(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rr(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_drdici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::drdici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DRDICI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::div_step_drdici_op_codes().count( op_code)) { execute_div_step_drdici(instruction); } else if (abi::instruction::Instruction::mul_step_drdici_op_codes().count( op_code)) { execute_mul_step_drdici(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_div_step_drdici( abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::div_step_drdici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DRDICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t dbe = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->even_reg(), abi::word::SIGNED); int64_t dbo = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->odd_reg(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); auto dbo_data_word = new abi::word::DataWord(); dbo_data_word->set_value(dbo); auto ra_shift_data_word = new abi::word::DataWord(); ra_shift_data_word->set_value(ALU::lsl(ra, imm)); auto [result, carry, overflow] = ALU::sub(dbo, ALU::lsl(ra, imm)); int64_t dce; int64_t dco; if (dbo_data_word->value(abi::word::UNSIGNED) >= ra_shift_data_word->value(abi::word::UNSIGNED)) { dce = ALU::lsl1(dbe, 1); dco = result; } else { dce = ALU::lsl(dbe, 1); dco = instruction->thread()->reg_file()->read_gp_reg( instruction->dc()->odd_reg(), abi::word::SIGNED); } instruction->thread()->reg_file()->clear_conditions(); set_div_cc(instruction, ra); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->even_reg(), dce); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->odd_reg(), dco); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, false); delete dbo_data_word; delete ra_shift_data_word; } void Logic::execute_mul_step_drdici( abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::mul_step_drdici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DRDICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t dbe = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->even_reg(), abi::word::SIGNED); int64_t dbo = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->odd_reg(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result1 = ALU::lsr(dbe, 1); auto [result2, carry, overflow] = ALU::sub(ALU::and_(dbe, 1), 1); int64_t dco; if (result2 == 0) { std::tie(dco, carry, overflow) = ALU::add(dbo, ALU::lsl(ra, imm)); } else { dco = instruction->thread()->reg_file()->read_gp_reg( instruction->dc()->odd_reg(), abi::word::SIGNED); } int64_t dce = ALU::lsr(dbe, 1); instruction->thread()->reg_file()->clear_conditions(); set_boot_cc(instruction, ra, result1); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->even_reg(), dce); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->odd_reg(), dco); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result1, false); } void Logic::execute_rrri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LSL_ADD) { std::tie(result, carry, overflow) = ALU::lsl_add(ra, rb, imm); } else if (op_code == abi::instruction::LSL_SUB) { std::tie(result, carry, overflow) = ALU::lsl_sub(ra, rb, imm); } else if (op_code == abi::instruction::LSR_ADD) { std::tie(result, carry, overflow) = ALU::lsr_add(ra, rb, imm); } else if (op_code == abi::instruction::ROL_ADD) { std::tie(result, carry, overflow) = ALU::rol_add(ra, rb, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rrrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RRRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LSL_ADD) { std::tie(result, carry, overflow) = ALU::lsl_add(ra, rb, imm); } else if (op_code == abi::instruction::LSL_SUB) { std::tie(result, carry, overflow) = ALU::lsl_sub(ra, rb, imm); } else if (op_code == abi::instruction::LSR_ADD) { std::tie(result, carry, overflow) = ALU::lsr_add(ra, rb, imm); } else if (op_code == abi::instruction::ROL_ADD) { std::tie(result, carry, overflow) = ALU::rol_add(ra, rb, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_div_nz_cc(instruction, ra); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_zrri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LSL_ADD) { std::tie(result, carry, overflow) = ALU::lsl_add(ra, rb, imm); } else if (op_code == abi::instruction::LSL_SUB) { std::tie(result, carry, overflow) = ALU::lsl_sub(ra, rb, imm); } else if (op_code == abi::instruction::LSR_ADD) { std::tie(result, carry, overflow) = ALU::lsr_add(ra, rb, imm); } else if (op_code == abi::instruction::ROL_ADD) { std::tie(result, carry, overflow) = ALU::rol_add(ra, rb, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_zrrici(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rrrici_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZRRICI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LSL_ADD) { std::tie(result, carry, overflow) = ALU::lsl_add(ra, rb, imm); } else if (op_code == abi::instruction::LSL_SUB) { std::tie(result, carry, overflow) = ALU::lsl_sub(ra, rb, imm); } else if (op_code == abi::instruction::LSR_ADD) { std::tie(result, carry, overflow) = ALU::lsr_add(ra, rb, imm); } else if (op_code == abi::instruction::ROL_ADD) { std::tie(result, carry, overflow) = ALU::rol_add(ra, rb, imm); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_div_nz_cc(instruction, ra); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_s_rrri(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rrrici(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrri(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rrrici(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_rir(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rir_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RIR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rirc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rirc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RIRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_set_cc(instruction, ra, imm, result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 1); } else { instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), 0); } instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_rirci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rirci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::RIRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_zir(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rir_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZIR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_zirc(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rirc_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZIRC); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_set_cc(instruction, ra, imm, result); instruction->thread()->reg_file()->increment_pc_reg(); set_flags(instruction, result, carry); } void Logic::execute_zirci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::rirci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ZIRCI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); int64_t result; bool carry; bool overflow; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SUB) { std::tie(result, carry, overflow) = ALU::sub(imm, ra); } else if (op_code == abi::instruction::SUBC) { std::tie(result, carry, overflow) = ALU::subc( imm, ra, instruction->thread()->reg_file()->flag(abi::isa::CARRY)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); set_sub_nz_cc(instruction, ra, imm, result, carry, overflow); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } set_flags(instruction, result, carry); } void Logic::execute_s_rirc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rirci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rirc(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rirci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_r(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_rci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_z(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::r_op_codes().count( instruction->op_code()) or instruction->op_code() == abi::instruction::NOP); assert(instruction->suffix() == abi::instruction::Z); instruction->thread()->reg_file()->increment_pc_reg(); } void Logic::execute_zci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_r(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_s_rci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_r(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_rci(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_ci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::ci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::CI); instruction->thread()->reg_file()->clear_conditions(); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); scheduler_->sleep(instruction->thread()->id()); } else { instruction->thread()->reg_file()->increment_pc_reg(); scheduler_->sleep(instruction->thread()->id()); } } void Logic::execute_i(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_ddci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::ddci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DDCI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::movd_ddci_op_codes().count(op_code)) { execute_movd_ddci(instruction); } else if (abi::instruction::Instruction::swapd_ddci_op_codes().count( op_code)) { execute_swapd_ddci(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_movd_ddci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::movd_ddci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DDCI); int64_t dbe = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->even_reg(), abi::word::SIGNED); int64_t dbo = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->odd_reg(), abi::word::SIGNED); instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->even_reg(), dbe); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->odd_reg(), dbo); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } } void Logic::execute_swapd_ddci(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::swapd_ddci_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DDCI); int64_t dbe = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->even_reg(), abi::word::SIGNED); int64_t dbo = instruction->thread()->reg_file()->read_gp_reg( instruction->db()->odd_reg(), abi::word::SIGNED); instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->even_reg(), dbo); instruction->thread()->reg_file()->write_gp_reg(instruction->dc()->odd_reg(), dbe); if (instruction->thread()->reg_file()->condition(instruction->condition())) { instruction->thread()->reg_file()->write_pc_reg(instruction->pc()->value()); } else { instruction->thread()->reg_file()->increment_pc_reg(); } } void Logic::execute_erri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::erri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ERRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t off = instruction->off()->value(); auto [address, carry, overflow] = ALU::add(ra, off); int64_t result; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LBS) { result = operand_collector_->lbs(address); } else if (op_code == abi::instruction::LBU) { result = operand_collector_->lbu(address); } else if (op_code == abi::instruction::LHS) { result = operand_collector_->lhs(address); } else if (op_code == abi::instruction::LHU) { result = operand_collector_->lhu(address); } else if (op_code == abi::instruction::LW) { result = operand_collector_->lw(address); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_gp_reg(instruction->rc(), result); instruction->thread()->reg_file()->increment_pc_reg(); } void Logic::execute_s_erri(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_u_erri(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_edri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::edri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::EDRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t off = instruction->off()->value(); auto [address, carry, overflow] = ALU::add(ra, off); int64_t even; int64_t odd; abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::LD) { std::tie(even, odd) = operand_collector_->ld(address); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->write_pair_reg(instruction->dc(), even, odd); instruction->thread()->reg_file()->increment_pc_reg(); } void Logic::execute_erii(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::erii_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ERII); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t off = instruction->off()->value(); int64_t imm = instruction->imm()->value(); auto [address, carry, overflow] = ALU::add(ra, off); abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SB) { operand_collector_->sb(address, imm); } else if (op_code == abi::instruction::SB_ID) { operand_collector_->sb(address, ALU::or_(instruction->thread()->id(), imm)); } else if (op_code == abi::instruction::SH) { operand_collector_->sh(address, imm); } else if (op_code == abi::instruction::SH_ID) { operand_collector_->sh(address, ALU::or_(instruction->thread()->id(), imm)); } else if (op_code == abi::instruction::SW) { operand_collector_->sw(address, imm); } else if (op_code == abi::instruction::SW_ID) { operand_collector_->sw(address, ALU::or_(instruction->thread()->id(), imm)); } else if (op_code == abi::instruction::SD) { auto [even, odd] = ALU::unsigned_extension(imm); operand_collector_->sd(address, even, odd); } else if (op_code == abi::instruction::SD_ID) { auto [even, odd] = ALU::unsigned_extension(ALU::or_(instruction->thread()->id(), imm)); operand_collector_->sd(address, even, odd); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); } void Logic::execute_erir(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::erir_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ERIR); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t off = instruction->off()->value(); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); auto rb_data_word = new abi::word::DataWord(); rb_data_word->set_value(rb); auto [address, carry, overflow] = ALU::add(ra, off); abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SB) { operand_collector_->sb(address, rb_data_word->bit_slice(abi::word::UNSIGNED, 0, 8)); } else if (op_code == abi::instruction::SH) { operand_collector_->sh(address, rb_data_word->bit_slice(abi::word::UNSIGNED, 0, 16)); } else if (op_code == abi::instruction::SW) { operand_collector_->sw(address, rb_data_word->bit_slice(abi::word::UNSIGNED, 0, 32)); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); delete rb_data_word; } void Logic::execute_erid(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::erid_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::ERID); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t off = instruction->off()->value(); auto [even, odd] = instruction->thread()->reg_file()->read_pair_reg( instruction->db(), abi::word::SIGNED); auto [address, carry, overflow] = ALU::add(ra, off); abi::instruction::OpCode op_code = instruction->op_code(); if (op_code == abi::instruction::SD) { operand_collector_->sd(address, even, odd); } else { throw std::invalid_argument(""); } instruction->thread()->reg_file()->clear_conditions(); instruction->thread()->reg_file()->increment_pc_reg(); } void Logic::execute_dma_rri(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::dma_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DMA_RRI); abi::instruction::OpCode op_code = instruction->op_code(); if (abi::instruction::Instruction::ldma_dma_rri_op_codes().count(op_code)) { execute_ldma(instruction); } else if (abi::instruction::Instruction::ldmai_dma_rri_op_codes().count( op_code)) { execute_ldmai(instruction); } else if (abi::instruction::Instruction::sdma_dma_rri_op_codes().count( op_code)) { execute_sdma(instruction); } else { throw std::invalid_argument(""); } } void Logic::execute_ldma(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::ldma_dma_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DMA_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); Address wram_end_address = util::ConfigLoader::wram_offset() + util::ConfigLoader::wram_size(); auto wram_end_address_width = static_cast
(floor(log2(wram_end_address)) + 1); auto wram_mask = static_cast
(pow(2, wram_end_address_width) - 1); Address wram_address = ALU::and_(ra, wram_mask); Address mram_end_address = util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size(); auto mram_end_address_width = static_cast
(floor(log2(mram_end_address)) + 1); auto mram_mask = static_cast
(pow(2, mram_end_address_width) - 1); Address mram_address = ALU::and_(rb, mram_mask); Address min_access_granularity = util::ConfigLoader::min_access_granularity(); Address size = (1 + ALU::and_(imm + ALU::and_(ALU::lsr(ra, 24), 255), 255)) * min_access_granularity; dma_->transfer_from_mram_to_wram(wram_address, mram_address, size, instruction); stat_factory_->overwrite("mram_address", mram_address); stat_factory_->overwrite("mram_access_thread", instruction->thread()->id()); stat_factory_->overwrite("mram_access_size", size); instruction->thread()->reg_file()->clear_conditions(); } void Logic::execute_ldmai(abi::instruction::Instruction *instruction) { throw std::bad_function_call(); } void Logic::execute_sdma(abi::instruction::Instruction *instruction) { assert(abi::instruction::Instruction::sdma_dma_rri_op_codes().count( instruction->op_code())); assert(instruction->suffix() == abi::instruction::DMA_RRI); int64_t ra = instruction->thread()->reg_file()->read_src_reg( instruction->ra(), abi::word::SIGNED); int64_t rb = instruction->thread()->reg_file()->read_src_reg( instruction->rb(), abi::word::SIGNED); int64_t imm = instruction->imm()->value(); Address wram_end_address = util::ConfigLoader::wram_offset() + util::ConfigLoader::wram_size(); auto wram_end_address_width = static_cast
(floor(log2(wram_end_address)) + 1); auto wram_mask = static_cast
(pow(2, wram_end_address_width) - 1); Address wram_address = ALU::and_(ra, wram_mask); Address mram_end_address = util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size(); auto mram_end_address_width = static_cast
(floor(log2(mram_end_address)) + 1); auto mram_mask = static_cast
(pow(2, mram_end_address_width) - 1); Address mram_address = ALU::and_(rb, mram_mask); Address min_access_granularity = util::ConfigLoader::min_access_granularity(); Address size = (1 + ALU::and_(imm + ALU::and_(ALU::lsr(ra, 24), 255), 255)) * min_access_granularity; dma_->transfer_from_wram_to_mram(wram_address, mram_address, size, instruction); stat_factory_->overwrite("mram_address", mram_address); stat_factory_->overwrite("mram_access_thread", instruction->thread()->id()); stat_factory_->overwrite("mram_access_size", size); instruction->thread()->reg_file()->clear_conditions(); } void Logic::set_acquire_cc(abi::instruction::Instruction *instruction, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } } void Logic::set_add_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result, bool carry, bool overflow) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (carry) { instruction->thread()->reg_file()->set_condition(abi::isa::C); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NC); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (overflow) { instruction->thread()->reg_file()->set_condition(abi::isa::OV); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NOV); } if (result >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::PL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::MI); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } auto result_data_word = new abi::word::DataWord(); result_data_word->set_value(result); if (result_data_word->bit(6)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC5); } if (result_data_word->bit(7)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC6); } if (result_data_word->bit(8)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC7); } if (result_data_word->bit(9)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC8); } if (result_data_word->bit(10)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC9); } if (result_data_word->bit(11)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC10); } if (result_data_word->bit(12)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC11); } if (result_data_word->bit(13)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC12); } if (result_data_word->bit(14)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC13); } if (result_data_word->bit(15)) { instruction->thread()->reg_file()->set_condition(abi::isa::NC14); } delete result_data_word; } void Logic::set_boot_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } } void Logic::set_count_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } if (result == abi::word::DataWord().width()) { instruction->thread()->reg_file()->set_condition(abi::isa::MAX); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NMAX); } } void Logic::set_div_cc(abi::instruction::Instruction *instruction, int64_t operand1) { if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } } void Logic::set_div_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1) { if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } } void Logic::set_ext_sub_set_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result, bool carry, bool overflow) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (carry) { instruction->thread()->reg_file()->set_condition(abi::isa::C); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NC); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (overflow) { instruction->thread()->reg_file()->set_condition(abi::isa::OV); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NOV); } if (result >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::PL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::MI); } if (operand1 == operand2) { instruction->thread()->reg_file()->set_condition(abi::isa::EQ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NEQ); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); if (data_word1->value(abi::word::UNSIGNED) < data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LTU); } if (data_word1->value(abi::word::UNSIGNED) <= data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LEU); } if (data_word1->value(abi::word::UNSIGNED) > data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GTU); } if (data_word1->value(abi::word::UNSIGNED) >= data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GEU); } if (data_word1->value(abi::word::SIGNED) < data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LTS); } if (data_word1->value(abi::word::SIGNED) <= data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LES); } if (data_word1->value(abi::word::SIGNED) > data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GTS); } if (data_word1->value(abi::word::SIGNED) >= data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GES); } if (carry or instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XLEU); } if (carry and not instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XGTU); } if (instruction->thread()->reg_file()->flag(abi::isa::ZERO) and (result < 0 or overflow)) { instruction->thread()->reg_file()->set_condition(abi::isa::XLES); } if (not instruction->thread()->reg_file()->flag(abi::isa::ZERO) and (result >= 0 or overflow)) { instruction->thread()->reg_file()->set_condition(abi::isa::XGTS); } delete data_word1; delete data_word2; } void Logic::set_imm_shift_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (result % 2 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::E); } else { instruction->thread()->reg_file()->set_condition(abi::isa::O); } if (result >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::PL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::MI); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 % 2 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SE); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SO); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } } void Logic::set_log_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (result >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::PL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::MI); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } } void Logic::set_log_set_cc(abi::instruction::Instruction *instruction, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } } void Logic::set_mul_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (operand1 == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SNZ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } if (result < 256) { instruction->thread()->reg_file()->set_condition(abi::isa::SMALL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::LARGE); } } void Logic::set_sub_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result, bool carry, bool overflow) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (carry) { instruction->thread()->reg_file()->set_condition(abi::isa::C); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NC); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (overflow) { instruction->thread()->reg_file()->set_condition(abi::isa::OV); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NOV); } if (result >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::PL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::MI); } if (operand1 == operand2) { instruction->thread()->reg_file()->set_condition(abi::isa::EQ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NEQ); } if (operand1 >= 0) { instruction->thread()->reg_file()->set_condition(abi::isa::SPL); } else { instruction->thread()->reg_file()->set_condition(abi::isa::SMI); } auto data_word1 = new abi::word::DataWord(); data_word1->set_value(operand1); auto data_word2 = new abi::word::DataWord(); data_word2->set_value(operand2); if (data_word1->value(abi::word::UNSIGNED) < data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LTU); } if (data_word1->value(abi::word::UNSIGNED) <= data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LEU); } if (data_word1->value(abi::word::UNSIGNED) > data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GTU); } if (data_word1->value(abi::word::UNSIGNED) >= data_word2->value(abi::word::UNSIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GEU); } if (data_word1->value(abi::word::SIGNED) < data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LTS); } if (data_word1->value(abi::word::SIGNED) <= data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::LES); } if (data_word1->value(abi::word::SIGNED) > data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GTS); } if (data_word1->value(abi::word::SIGNED) >= data_word2->value(abi::word::SIGNED)) { instruction->thread()->reg_file()->set_condition(abi::isa::GES); } if (carry or instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XLEU); } if (carry and not instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XGTU); } if (instruction->thread()->reg_file()->flag(abi::isa::ZERO) and (result < 0 or overflow)) { instruction->thread()->reg_file()->set_condition(abi::isa::XLES); } if (not instruction->thread()->reg_file()->flag(abi::isa::ZERO) and (result >= 0 or overflow)) { instruction->thread()->reg_file()->set_condition(abi::isa::XGTS); } delete data_word1; delete data_word2; } void Logic::set_sub_set_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result) { if (result == 0) { instruction->thread()->reg_file()->set_condition(abi::isa::Z); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NZ); } if (result == 0 and instruction->thread()->reg_file()->flag(abi::isa::ZERO)) { instruction->thread()->reg_file()->set_condition(abi::isa::XZ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::XNZ); } if (operand1 == operand2) { instruction->thread()->reg_file()->set_condition(abi::isa::EQ); } else { instruction->thread()->reg_file()->set_condition(abi::isa::NEQ); } } void Logic::set_flags(abi::instruction::Instruction *instruction, int64_t result, bool carry) { if (result == 0) { instruction->thread()->reg_file()->set_flag(abi::isa::ZERO); } else { instruction->thread()->reg_file()->clear_flag(abi::isa::ZERO); } if (carry) { instruction->thread()->reg_file()->set_flag(abi::isa::CARRY); } else { instruction->thread()->reg_file()->clear_flag(abi::isa::CARRY); } } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/logic.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_LOGIC_H_ #define UPMEM_SIM_SIMULATOR_DPU_LOGIC_H_ #include "simulator/dpu/cycle_rule.h" #include "simulator/dpu/dma.h" #include "simulator/dpu/operand_collector.h" #include "simulator/dpu/pipeline.h" #include "simulator/dpu/revolver_scheduler.h" #include "simulator/dram/memory_controller.h" #include "simulator/sram/atomic.h" #include "simulator/sram/iram.h" #include "simulator/sram/wram.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dpu { class Logic { public: explicit Logic(DPUID dpu_id, util::ArgumentParser *argument_parser) : verbose_(argument_parser->get_int_parameter("verbose")), dpu_id_(dpu_id), scheduler_(nullptr), atomic_(nullptr), iram_(nullptr), dma_(nullptr), pipeline_(new Pipeline(argument_parser)), cycle_rule_(new CycleRule(argument_parser)), operand_collector_(nullptr), wait_instruction_q_(new basic::Queue( util::ConfigLoader::max_num_tasklets())), stat_factory_(new util::StatFactory("Logic")), num_pipeline_stages_( argument_parser->get_int_parameter("num_pipeline_stages")) {} ~Logic(); DPUID dpu_id() { return dpu_id_; } util::StatFactory *stat_factory(); void connect_scheduler(RevolverScheduler *scheduler); void connect_atomic(sram::Atomic *atomic); void connect_iram(sram::IRAM *iram); void connect_operand_collector(OperandCollector *operand_collector); void connect_dma(DMA *dma); bool empty() { return pipeline_->empty() and cycle_rule_->empty() and wait_instruction_q_->empty(); } void cycle(); protected: void service_scheduler(); void service_pipeline(); void service_cycle_rule(); void service_logic(); void service_dma(); void execute_instruction(abi::instruction::Instruction *instruction); void execute_rici(abi::instruction::Instruction *instruction); void execute_acquire_rici(abi::instruction::Instruction *instruction); void execute_release_rici(abi::instruction::Instruction *instruction); void execute_boot_rici(abi::instruction::Instruction *instruction); void execute_rri(abi::instruction::Instruction *instruction); void execute_add_rri(abi::instruction::Instruction *instruction); void execute_asr_rri(abi::instruction::Instruction *instruction); void execute_call_rri(abi::instruction::Instruction *instruction); void execute_rric(abi::instruction::Instruction *instruction); void execute_add_rric(abi::instruction::Instruction *instruction); void execute_asr_rric(abi::instruction::Instruction *instruction); void execute_sub_rric(abi::instruction::Instruction *instruction); void execute_rrici(abi::instruction::Instruction *instruction); void execute_add_rrici(abi::instruction::Instruction *instruction); void execute_and_rrici(abi::instruction::Instruction *instruction); void execute_asr_rrici(abi::instruction::Instruction *instruction); void execute_sub_rrici(abi::instruction::Instruction *instruction); void execute_rrif(abi::instruction::Instruction *instruction); void execute_rrr(abi::instruction::Instruction *instruction); void execute_rrrc(abi::instruction::Instruction *instruction); void execute_add_rrrc(abi::instruction::Instruction *instruction); void execute_rsub_rrrc(abi::instruction::Instruction *instruction); void execute_sub_rrrc(abi::instruction::Instruction *instruction); void execute_rrrci(abi::instruction::Instruction *instruction); void execute_add_rrrci(abi::instruction::Instruction *instruction); void execute_and_rrrci(abi::instruction::Instruction *instruction); void execute_asr_rrrci(abi::instruction::Instruction *instruction); void execute_mul_rrrci(abi::instruction::Instruction *instruction); void execute_rsub_rrrci(abi::instruction::Instruction *instruction); void execute_zri(abi::instruction::Instruction *instruction); void execute_add_zri(abi::instruction::Instruction *instruction); void execute_asr_zri(abi::instruction::Instruction *instruction); void execute_call_zri(abi::instruction::Instruction *instruction); void execute_zric(abi::instruction::Instruction *instruction); void execute_add_zric(abi::instruction::Instruction *instruction); void execute_asr_zric(abi::instruction::Instruction *instruction); void execute_sub_zric(abi::instruction::Instruction *instruction); void execute_zrici(abi::instruction::Instruction *instruction); void execute_add_zrici(abi::instruction::Instruction *instruction); void execute_and_zrici(abi::instruction::Instruction *instruction); void execute_asr_zrici(abi::instruction::Instruction *instruction); void execute_sub_zrici(abi::instruction::Instruction *instruction); void execute_zrif(abi::instruction::Instruction *instruction); void execute_zrr(abi::instruction::Instruction *instruction); void execute_zrrc(abi::instruction::Instruction *instruction); void execute_add_zrrc(abi::instruction::Instruction *instruction); void execute_rsub_zrrc(abi::instruction::Instruction *instruction); void execute_sub_zrrc(abi::instruction::Instruction *instruction); void execute_zrrci(abi::instruction::Instruction *instruction); void execute_add_zrrci(abi::instruction::Instruction *instruction); void execute_and_zrrci(abi::instruction::Instruction *instruction); void execute_asr_zrrci(abi::instruction::Instruction *instruction); void execute_mul_zrrci(abi::instruction::Instruction *instruction); void execute_rsub_zrrci(abi::instruction::Instruction *instruction); void execute_s_rri(abi::instruction::Instruction *instruction); void execute_add_s_rri(abi::instruction::Instruction *instruction); void execute_asr_s_rri(abi::instruction::Instruction *instruction); void execute_s_rric(abi::instruction::Instruction *instruction); void execute_s_rrici(abi::instruction::Instruction *instruction); void execute_add_s_rrici(abi::instruction::Instruction *instruction); void execute_and_s_rrici(abi::instruction::Instruction *instruction); void execute_asr_s_rrici(abi::instruction::Instruction *instruction); void execute_sub_s_rrici(abi::instruction::Instruction *instruction); void execute_s_rrif(abi::instruction::Instruction *instruction); void execute_s_rrr(abi::instruction::Instruction *instruction); void execute_s_rrrc(abi::instruction::Instruction *instruction); void execute_s_rrrci(abi::instruction::Instruction *instruction); void execute_u_rri(abi::instruction::Instruction *instruction); void execute_add_u_rri(abi::instruction::Instruction *instruction); void execute_asr_u_rri(abi::instruction::Instruction *instruction); void execute_u_rric(abi::instruction::Instruction *instruction); void execute_u_rrici(abi::instruction::Instruction *instruction); void execute_add_u_rrici(abi::instruction::Instruction *instruction); void execute_and_u_rrici(abi::instruction::Instruction *instruction); void execute_asr_u_rrici(abi::instruction::Instruction *instruction); void execute_sub_u_rrici(abi::instruction::Instruction *instruction); void execute_u_rrif(abi::instruction::Instruction *instruction); void execute_u_rrr(abi::instruction::Instruction *instruction); void execute_u_rrrc(abi::instruction::Instruction *instruction); void execute_u_rrrci(abi::instruction::Instruction *instruction); void execute_rr(abi::instruction::Instruction *instruction); void execute_rrc(abi::instruction::Instruction *instruction); void execute_rrci(abi::instruction::Instruction *instruction); void execute_cao_rrci(abi::instruction::Instruction *instruction); void execute_extsb_rrci(abi::instruction::Instruction *instruction); void execute_time_cfg_rrci(abi::instruction::Instruction *instruction); void execute_zr(abi::instruction::Instruction *instruction); void execute_zrc(abi::instruction::Instruction *instruction); void execute_zrci(abi::instruction::Instruction *instruction); void execute_cao_zrci(abi::instruction::Instruction *instruction); void execute_extsb_zrci(abi::instruction::Instruction *instruction); void execute_time_cfg_zrci(abi::instruction::Instruction *instruction); void execute_s_rr(abi::instruction::Instruction *instruction); void execute_s_rrc(abi::instruction::Instruction *instruction); void execute_s_rrci(abi::instruction::Instruction *instruction); void execute_u_rr(abi::instruction::Instruction *instruction); void execute_u_rrc(abi::instruction::Instruction *instruction); void execute_u_rrci(abi::instruction::Instruction *instruction); void execute_drdici(abi::instruction::Instruction *instruction); void execute_div_step_drdici(abi::instruction::Instruction *instruction); void execute_mul_step_drdici(abi::instruction::Instruction *instruction); void execute_rrri(abi::instruction::Instruction *instruction); void execute_rrrici(abi::instruction::Instruction *instruction); void execute_zrri(abi::instruction::Instruction *instruction); void execute_zrrici(abi::instruction::Instruction *instruction); void execute_s_rrri(abi::instruction::Instruction *instruction); void execute_s_rrrici(abi::instruction::Instruction *instruction); void execute_u_rrri(abi::instruction::Instruction *instruction); void execute_u_rrrici(abi::instruction::Instruction *instruction); void execute_rir(abi::instruction::Instruction *instruction); void execute_rirc(abi::instruction::Instruction *instruction); void execute_rirci(abi::instruction::Instruction *instruction); void execute_zir(abi::instruction::Instruction *instruction); void execute_zirc(abi::instruction::Instruction *instruction); void execute_zirci(abi::instruction::Instruction *instruction); void execute_s_rirc(abi::instruction::Instruction *instruction); void execute_s_rirci(abi::instruction::Instruction *instruction); void execute_u_rirc(abi::instruction::Instruction *instruction); void execute_u_rirci(abi::instruction::Instruction *instruction); void execute_r(abi::instruction::Instruction *instruction); void execute_rci(abi::instruction::Instruction *instruction); void execute_z(abi::instruction::Instruction *instruction); void execute_zci(abi::instruction::Instruction *instruction); void execute_s_r(abi::instruction::Instruction *instruction); void execute_s_rci(abi::instruction::Instruction *instruction); void execute_u_r(abi::instruction::Instruction *instruction); void execute_u_rci(abi::instruction::Instruction *instruction); void execute_ci(abi::instruction::Instruction *instruction); void execute_i(abi::instruction::Instruction *instruction); void execute_ddci(abi::instruction::Instruction *instruction); void execute_movd_ddci(abi::instruction::Instruction *instruction); void execute_swapd_ddci(abi::instruction::Instruction *instruction); void execute_erri(abi::instruction::Instruction *instruction); void execute_s_erri(abi::instruction::Instruction *instruction); void execute_u_erri(abi::instruction::Instruction *instruction); void execute_edri(abi::instruction::Instruction *instruction); void execute_erii(abi::instruction::Instruction *instruction); void execute_erir(abi::instruction::Instruction *instruction); void execute_erid(abi::instruction::Instruction *instruction); void execute_dma_rri(abi::instruction::Instruction *instruction); void execute_ldma(abi::instruction::Instruction *instruction); void execute_ldmai(abi::instruction::Instruction *instruction); void execute_sdma(abi::instruction::Instruction *instruction); void set_acquire_cc(abi::instruction::Instruction *instruction, int64_t result); void set_add_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result, bool carry, bool overflow); void set_boot_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result); void set_count_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result); void set_div_cc(abi::instruction::Instruction *instruction, int64_t operand1); void set_div_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1); void set_ext_sub_set_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result, bool carry, bool overflow); void set_imm_shift_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result); void set_log_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result); void set_log_set_cc(abi::instruction::Instruction *instruction, int64_t result); void set_mul_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t result); void set_sub_nz_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result, bool carry, bool overflow); void set_sub_set_cc(abi::instruction::Instruction *instruction, int64_t operand1, int64_t operand2, int64_t result); void set_flags(abi::instruction::Instruction *instruction, int64_t result, bool carry); private: DPUID dpu_id_; int verbose_; RevolverScheduler *scheduler_; sram::Atomic *atomic_; sram::IRAM *iram_; DMA *dma_; Pipeline *pipeline_; int num_pipeline_stages_; CycleRule *cycle_rule_; OperandCollector *operand_collector_; basic::Queue *wait_instruction_q_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/operand_collector.cc ================================================ #include "simulator/dpu/operand_collector.h" #include namespace upmem_sim::simulator::dpu { void OperandCollector::connect_wram(sram::WRAM *wram) { assert(wram != nullptr); assert(wram_ == nullptr); wram_ = wram; } int64_t OperandCollector::lbs(Address address) { Address data_word_size = abi::word::DataWord().size(); Address base_address = (address / data_word_size) * data_word_size; Address offset = address % data_word_size; auto data_word = new abi::word::DataWord(); data_word->set_value(wram_->read(base_address)); int64_t result = data_word->bit_slice(abi::word::SIGNED, static_cast(8 * offset), static_cast(8 * (offset + 1))); delete data_word; return result; } int64_t OperandCollector::lbu(Address address) { Address data_word_size = abi::word::DataWord().size(); Address base_address = (address / data_word_size) * data_word_size; Address offset = address % data_word_size; auto data_word = new abi::word::DataWord(); data_word->set_value(wram_->read(base_address)); int64_t result = data_word->bit_slice(abi::word::UNSIGNED, static_cast(8 * offset), static_cast(8 * (offset + 1))); delete data_word; return result; } int64_t OperandCollector::lhs(Address address) { auto data_word = new abi::word::DataWord(); data_word->set_bit_slice(0, 8, lbs(address)); data_word->set_bit_slice(8, 16, lbs(address + 1)); int64_t result = data_word->bit_slice(abi::word::SIGNED, 0, 16); delete data_word; return result; } int64_t OperandCollector::lhu(Address address) { auto data_word = new abi::word::DataWord(); data_word->set_bit_slice(0, 8, lbu(address)); data_word->set_bit_slice(8, 16, lbu(address + 1)); int64_t result = data_word->bit_slice(abi::word::UNSIGNED, 0, 16); delete data_word; return result; } int64_t OperandCollector::lw(Address address) { auto data_word = new abi::word::DataWord(); data_word->set_bit_slice(0, 8, lbu(address)); data_word->set_bit_slice(8, 16, lbu(address + 1)); data_word->set_bit_slice(16, 24, lbu(address + 2)); data_word->set_bit_slice(24, 32, lbu(address + 3)); int64_t result = data_word->value(abi::word::UNSIGNED); delete data_word; return result; } std::tuple OperandCollector::ld(Address address) { return {lw(address + abi::word::DataWord().size()), lw(address)}; } void OperandCollector::sb(Address address, int64_t value) { Address data_word_size = abi::word::DataWord().size(); Address base_address = (address / data_word_size) * data_word_size; Address offset = address % data_word_size; auto data_word = new abi::word::DataWord(); data_word->set_value(wram_->read(base_address)); data_word->set_bit_slice(static_cast(8 * offset), static_cast(8 * (offset + 1)), value); wram_->write(base_address, data_word->value(abi::word::UNSIGNED)); delete data_word; } void OperandCollector::sh(Address address, int64_t value) { auto data_word = new abi::word::DataWord(); data_word->set_value(value); sb(address, data_word->bit_slice(abi::word::UNSIGNED, 0, 8)); sb(address + 1, data_word->bit_slice(abi::word::UNSIGNED, 8, 16)); delete data_word; } void OperandCollector::sw(Address address, int64_t value) { auto data_word = new abi::word::DataWord(); data_word->set_value(value); sb(address, data_word->bit_slice(abi::word::UNSIGNED, 0, 8)); sb(address + 1, data_word->bit_slice(abi::word::UNSIGNED, 8, 16)); sb(address + 2, data_word->bit_slice(abi::word::UNSIGNED, 16, 24)); sb(address + 3, data_word->bit_slice(abi::word::UNSIGNED, 24, 32)); delete data_word; } void OperandCollector::sd(Address address, int64_t even, int64_t odd) { sw(address + abi::word::DataWord().size(), even); sw(address, odd); } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/operand_collector.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_OPERAND_COLLECTOR_H_ #define UPMEM_SIM_SIMULATOR_DPU_OPERAND_COLLECTOR_H_ #include "simulator/sram/wram.h" namespace upmem_sim::simulator::dpu { class OperandCollector { public: explicit OperandCollector() : wram_(nullptr) {} ~OperandCollector() = default; void connect_wram(sram::WRAM *wram); int64_t lbs(Address address); int64_t lbu(Address address); int64_t lhs(Address address); int64_t lhu(Address address); int64_t lw(Address address); std::tuple ld(Address address); void sb(Address address, int64_t value); void sh(Address address, int64_t value); void sw(Address address, int64_t value); void sd(Address address, int64_t even, int64_t odd); void cycle() = delete; private: sram::WRAM *wram_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/pipeline.cc ================================================ #include "simulator/dpu/pipeline.h" #include "converter/instruction_converter.h" namespace upmem_sim::simulator::dpu { Pipeline::Pipeline(util::ArgumentParser *argument_parser) : input_q_(new basic::Queue(1)), ready_q_(new basic::Queue(1)) { int num_pipeline_stages = static_cast( argument_parser->get_int_parameter("num_pipeline_stages")); assert(num_pipeline_stages > 1); wait_q_ = new basic::Queue(num_pipeline_stages - 1); while (wait_q_->can_push()) { wait_q_->push(nullptr); } ready_q_->push(nullptr); } Pipeline::~Pipeline() { while (wait_q_->can_pop()) { if (wait_q_->front() != nullptr) { converter::InstructionConverter::to_string(wait_q_->front()); } assert(wait_q_->pop() == nullptr); } while (ready_q_->can_pop()) { assert(ready_q_->pop() == nullptr); } delete input_q_; delete wait_q_; delete ready_q_; } void Pipeline::push(abi::instruction::Instruction *instruction) { assert(can_push()); assert(instruction != nullptr); input_q_->push(instruction); } void Pipeline::cycle() { service_input_q(); service_wait_q(); } bool Pipeline::empty_wait_q() { std::queue wait_q; while (wait_q_->can_pop()) { abi::instruction::Instruction *instruction = wait_q_->pop(); wait_q.push(instruction); } while (not wait_q.empty()) { abi::instruction::Instruction *instruction = wait_q.front(); wait_q.pop(); wait_q_->push(instruction); if (instruction != nullptr) { return false; } } return true; } void Pipeline::service_input_q() { if (input_q_->can_pop() and wait_q_->can_push()) { abi::instruction::Instruction *instruction = input_q_->pop(); wait_q_->push(instruction); } else if (wait_q_->can_push()) { wait_q_->push(nullptr); } } void Pipeline::service_wait_q() { if (wait_q_->can_pop() and ready_q_->can_push()) { abi::instruction::Instruction *instruction = wait_q_->pop(); ready_q_->push(instruction); } } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/pipeline.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_PIPELINE_H_ #define UPMEM_SIM_SIMULATOR_DPU_PIPELINE_H_ #include "abi/instruction/instruction.h" #include "simulator/basic/queue.h" #include "util/argument_parser.h" namespace upmem_sim::simulator::dpu { class Pipeline { public: explicit Pipeline(util::ArgumentParser *argument_parser); ~Pipeline(); bool empty() { return empty_input_q() and empty_wait_q() and empty_ready_q(); } bool can_push() { return input_q_->can_push(); } void push(abi::instruction::Instruction *instruction); bool can_pop() { return ready_q_->can_pop(); } abi::instruction::Instruction *pop() { return ready_q_->pop(); } void cycle(); protected: bool empty_input_q() { return input_q_->empty(); } bool empty_wait_q(); bool empty_ready_q() { return ready_q_->empty() or ready_q_->front() == nullptr; } void service_input_q(); void service_wait_q(); private: basic::Queue *input_q_; basic::Queue *wait_q_; basic::Queue *ready_q_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/revolver_scheduler.cc ================================================ #include "simulator/dpu/revolver_scheduler.h" namespace upmem_sim::simulator::dpu { RevolverScheduler::RevolverScheduler(util::ArgumentParser *argument_parser, std::vector threads) : thread_q_(new basic::Queue(threads.size())), stat_factory_(new util::StatFactory("RevolverScheduler")) { num_revolver_scheduling_cycles_ = static_cast( argument_parser->get_int_parameter("num_revolver_scheduling_cycles")); assert(num_revolver_scheduling_cycles_ > 0); threads_ = threads; for (auto &thread : threads) { thread_q_->push(thread); } } RevolverScheduler::~RevolverScheduler() { while (thread_q_->can_pop()) { thread_q_->pop(); } delete stat_factory_; } util::StatFactory *RevolverScheduler::stat_factory() { auto stat_factory = new util::StatFactory(""); stat_factory->merge(stat_factory_); return stat_factory; } Thread *RevolverScheduler::schedule() { bool is_blocked = false; for (int i = 0; i < thread_q_->size(); i++) { Thread *thread = thread_q_->pop(); thread_q_->push(thread); if (thread->issue_cycle() >= num_revolver_scheduling_cycles_) { if (thread->state() == Thread::RUNNABLE) { thread->reset_issue_cycle(); stat_factory_->increment("breakdown_run"); return thread; } else if (thread->state() == Thread::BLOCK) { is_blocked = true; } } } if (is_blocked) { stat_factory_->increment("breakdown_dma"); } else { stat_factory_->increment("breakdown_etc"); } return nullptr; } bool RevolverScheduler::boot(ThreadID id) { Thread *thread = threads_[id]; assert(thread->id() == id); if (thread->state() == Thread::EMBRYO) { thread->set_state(Thread::RUNNABLE); return true; } else if (thread->state() == Thread::ZOMBIE) { thread->set_state(Thread::RUNNABLE); return true; } else { throw std::invalid_argument(""); } } bool RevolverScheduler::sleep(ThreadID id) { Thread *thread = threads_[id]; assert(thread->id() == id); if (thread->state() == Thread::RUNNABLE) { thread->set_state(Thread::SLEEP); return true; } else { throw std::invalid_argument(""); } } bool RevolverScheduler::block(ThreadID id) { Thread *thread = threads_[id]; assert(thread->id() == id); if (thread->state() == Thread::RUNNABLE) { thread->set_state(Thread::BLOCK); return true; } else { throw std::invalid_argument(""); } } bool RevolverScheduler::awake(ThreadID id) { Thread *thread = threads_[id]; assert(thread->id() == id); if (thread->state() == Thread::EMBRYO) { thread->set_state(Thread::RUNNABLE); return true; } else if (thread->state() == Thread::SLEEP) { thread->set_state(Thread::RUNNABLE); return true; } else if (thread->state() == Thread::BLOCK) { thread->set_state(Thread::RUNNABLE); return true; } else { throw std::invalid_argument(""); } } bool RevolverScheduler::shutdown(ThreadID id) { Thread *thread = threads_[id]; assert(thread->id() == id); if (thread->state() == Thread::SLEEP) { thread->set_state(Thread::ZOMBIE); return true; } else { throw std::invalid_argument(""); } } void RevolverScheduler::cycle() { int num_active_tasklets = 0, num_embryo = 0, num_sleep = 0, num_block = 0, num_zombie = 0; for (auto &thread : threads_) { if (thread->state() == Thread::RUNNABLE and thread->issue_cycle() < num_revolver_scheduling_cycles_) { stat_factory_->increment("revolver_wait"); stat_factory_->increment(std::to_string(thread->id()) + "_revolver_wait"); } thread->increment_issue_cycle(); if (thread->state() == Thread::RUNNABLE) num_active_tasklets++; else if (thread->state() == Thread::EMBRYO) num_embryo++; else if (thread->state() == Thread::SLEEP) num_sleep++; else if (thread->state() == Thread::BLOCK) num_block++; else if (thread->state() == Thread::ZOMBIE) num_zombie++; else assert(0); } assert(num_active_tasklets <= 16); stat_factory_->overwrite("current_active_tasklets", num_active_tasklets); stat_factory_->increment("active_tasklets_" + std::to_string(num_active_tasklets)); stat_factory_->increment("total_EMBRYO", num_embryo); stat_factory_->increment("total_RUNNABLE", num_active_tasklets); stat_factory_->increment("total_SLEEP", num_sleep); stat_factory_->increment("total_BLOCK", num_block); stat_factory_->increment("total_ZOMBIE", num_zombie); issuable_threads_ = num_active_tasklets; } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/revolver_scheduler.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_REVOLVER_SCHEDULER_H_ #define UPMEM_SIM_SIMULATOR_DPU_REVOLVER_SCHEDULER_H_ #include #include "simulator/basic/queue.h" #include "simulator/dpu/thread.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dpu { class RevolverScheduler { public: explicit RevolverScheduler(util::ArgumentParser *argument_parser, std::vector threads); ~RevolverScheduler(); util::StatFactory *stat_factory(); std::vector threads() { return threads_; } Thread *schedule(); bool boot(ThreadID id); bool sleep(ThreadID id); bool block(ThreadID id); bool awake(ThreadID id); bool shutdown(ThreadID id); void cycle(); int get_issuable_threads() { return issuable_threads_; }; private: int num_revolver_scheduling_cycles_; int issuable_threads_; std::vector threads_; basic::Queue *thread_q_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/thread.cc ================================================ #include "simulator/dpu/thread.h" namespace upmem_sim::simulator::dpu { Thread::~Thread() { assert(state_ == ZOMBIE); delete reg_file_; } } // namespace upmem_sim::simulator::dpu ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dpu/thread.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DPU_THREAD_H_ #define UPMEM_SIM_SIMULATOR_DPU_THREAD_H_ #include #include #include "simulator/reg/reg_file.h" #include "util/config_loader.h" namespace upmem_sim::simulator::dpu { using ThreadStatus = std::string; class Thread { public: enum State { EMBRYO = 0, RUNNABLE, SLEEP, BLOCK, ZOMBIE }; explicit Thread(ThreadID id) : id_(id), state_(EMBRYO), reg_file_(new reg::RegFile(id_)), issue_cycle_(0) { assert(0 <= id and id < upmem_sim::util::ConfigLoader::max_num_tasklets()); status_tracker_.emplace("WAIT_DATA", 0); status_tracker_.emplace("WAIT_SYNC", 0); status_tracker_.emplace("ARITHMETIC", 0); status_tracker_.emplace("SPM_ACCESS", 0); status_tracker_.emplace("WAIT_SCHEDULE", 0); } ~Thread(); ThreadID id() { return id_; } State state() { return state_; } void set_state(State state) { state_ = state; } reg::RegFile *reg_file() { return reg_file_; } int issue_cycle() { return issue_cycle_; } void increment_issue_cycle() { issue_cycle_ += 1; } void reset_issue_cycle() { issue_cycle_ = 0; } void update_thread_status(ThreadStatus status, int64_t value) { status_tracker_[std::move(status)] += value; } std::map &status_tracker() { return status_tracker_; } private: ThreadID id_; State state_; std::map status_tracker_; reg::RegFile *reg_file_; int issue_cycle_; }; } // namespace upmem_sim::simulator::dpu #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/fifo_scheduler.cc ================================================ #include "simulator/dram/fifo_scheduler.h" namespace upmem_sim::simulator::dram { void FIFOScheduler::cycle() { service_input_q(); service_output_q(); } void FIFOScheduler::service_input_q() { if (input_q_->can_pop()) { dpu::DMACommand *dma_command = input_q_->pop(); service_dma_command(dma_command); } } void FIFOScheduler::service_dma_command(dpu::DMACommand *dma_command) { Address begin_address = dma_command->mram_address(); Address end_address = dma_command->mram_address() + dma_command->size(); Address address = begin_address; while (address < end_address) { Address min_access_granularity = util::ConfigLoader::min_access_granularity(); Address wordline_address = (address / wordline_size_) * wordline_size_ + wordline_size_; Address size = std::min(std::min(address + min_access_granularity, wordline_address), end_address) - address; reorder_buffer_.push_back({dma_command, address, size}); address += size; } } void FIFOScheduler::service_output_q() { if (not reorder_buffer_.empty()) { service_fcfs(); } } bool FIFOScheduler::service_fcfs() { auto [dma_command, address, size] = reorder_buffer_[0]; Address wordline_address = (address / wordline_size_) * wordline_size_; if (row_address_ == nullptr and ready_q_->can_push(2)) { reorder_buffer_.erase(reorder_buffer_.begin()); ready_q_->push( new MemoryCommand(MemoryCommand::ACTIVATION, wordline_address)); row_address_ = new abi::word::DataAddressWord(); row_address_->set_value(wordline_address); if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push( new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); } else { throw std::invalid_argument(""); } stat_factory_->increment("row_buffer_miss"); return true; } else if (row_address_ != nullptr and row_address_->address() == wordline_address and ready_q_->can_push(1)) { reorder_buffer_.erase(reorder_buffer_.begin()); if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push( new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); } else { throw std::invalid_argument(""); } stat_factory_->increment("row_buffer_hit"); return true; } else if (row_address_ != nullptr and row_address_->address() != wordline_address and ready_q_->can_push(3)) { reorder_buffer_.erase(reorder_buffer_.begin()); ready_q_->push( new MemoryCommand(MemoryCommand::PRECHARGE, row_address_->address())); ready_q_->push( new MemoryCommand(MemoryCommand::ACTIVATION, wordline_address)); row_address_->set_value(wordline_address); if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push( new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); } else { throw std::invalid_argument(""); } stat_factory_->increment("row_buffer_miss"); return true; } else { return false; } } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/fifo_scheduler.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_FIFO_SCHEDULER_H_ #define UPMEM_SIM_SIMULATOR_DRAM_FIFO_SCHEDULER_H_ #include "simulator/dram/scheduler.h" #include "util/argument_parser.h" namespace upmem_sim::simulator::dram { class FIFOScheduler : public Scheduler { public: explicit FIFOScheduler(util::ArgumentParser *argument_parser) : Scheduler(argument_parser) {} ~FIFOScheduler() { assert(reorder_buffer_.empty()); } void cycle() final; protected: void service_input_q(); void service_dma_command(dpu::DMACommand *dma_command); void service_output_q(); bool service_fcfs(); }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/frfcfs_scheduler.cc ================================================ #include "simulator/dram/frfcfs_scheduler.h" namespace upmem_sim::simulator::dram { void FRFCFSScheduler::cycle() { service_input_q(); service_output_q(); } void FRFCFSScheduler::service_input_q() { if (input_q_->can_pop()) { dpu::DMACommand *dma_command = input_q_->pop(); service_dma_command(dma_command); } } void FRFCFSScheduler::service_dma_command(dpu::DMACommand *dma_command) { Address begin_address = dma_command->mram_address(); Address end_address = dma_command->mram_address() + dma_command->size(); Address address = begin_address; while (address < end_address) { Address min_access_granularity = util::ConfigLoader::min_access_granularity(); Address wordline_address = (address / wordline_size_) * wordline_size_ + wordline_size_; Address size = std::min(std::min(address + min_access_granularity, wordline_address), end_address) - address; reorder_buffer_.push_back({dma_command, address, size}); address += size; } } void FRFCFSScheduler::service_output_q() { if (not reorder_buffer_.empty()) { bool is_fr = service_fr(); if (not is_fr) { service_fcfs(); } } } bool FRFCFSScheduler::service_fr() { if (row_address_ == nullptr) { return false; } else { for (int i = 0; i < reorder_buffer_.size(); i++) { auto [dma_command, address, size] = reorder_buffer_[i]; Address wordline_address = (address / wordline_size_) * wordline_size_; if (row_address_->address() == wordline_address and ready_q_->can_push(1)) { if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push(new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); reorder_buffer_.erase(reorder_buffer_.begin() + i); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); reorder_buffer_.erase(reorder_buffer_.begin() + i); } else { throw std::invalid_argument(""); } if (i != 0) { stat_factory_->increment("num_fr"); } else { stat_factory_->increment("num_fcfs"); } stat_factory_->increment("row_buffer_hit"); return true; } } return false; } } bool FRFCFSScheduler::service_fcfs() { if (row_address_ == nullptr and ready_q_->can_push(2)) { auto [dma_command, address, size] = reorder_buffer_[0]; reorder_buffer_.erase(reorder_buffer_.begin()); Address wordline_address = (address / wordline_size_) * wordline_size_; ready_q_->push( new MemoryCommand(MemoryCommand::ACTIVATION, wordline_address)); row_address_ = new abi::word::DataAddressWord(); row_address_->set_value(wordline_address); if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push( new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); } else { throw std::invalid_argument(""); } stat_factory_->increment("row_buffer_miss"); return true; } else if (row_address_ != nullptr and ready_q_->can_push(3)) { auto [dma_command, address, size] = reorder_buffer_[0]; reorder_buffer_.erase(reorder_buffer_.begin()); Address wordline_address = (address / wordline_size_) * wordline_size_; ready_q_->push( new MemoryCommand(MemoryCommand::PRECHARGE, row_address_->address())); ready_q_->push( new MemoryCommand(MemoryCommand::ACTIVATION, wordline_address)); row_address_->set_value(wordline_address); if (dma_command->operation() == dpu::DMACommand::READ) { ready_q_->push( new MemoryCommand(MemoryCommand::READ, address, size, dma_command)); } else if (dma_command->operation() == dpu::DMACommand::WRITE) { ready_q_->push(new MemoryCommand(MemoryCommand::WRITE, address, size, dma_command->bytes(address, size), dma_command)); } else { throw std::invalid_argument(""); } stat_factory_->increment("row_buffer_miss"); return true; } else { return false; } } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/frfcfs_scheduler.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_FRFCFS_SCHEDULER_H_ #define UPMEM_SIM_SIMULATOR_DRAM_FRFCFS_SCHEDULER_H_ #include "simulator/dram/scheduler.h" #include "util/argument_parser.h" namespace upmem_sim::simulator::dram { class FRFCFSScheduler : public Scheduler { public: explicit FRFCFSScheduler(util::ArgumentParser *argument_parser) : Scheduler(argument_parser) {} ~FRFCFSScheduler() { assert(reorder_buffer_.empty()); } void cycle() final; protected: void service_input_q(); void service_dma_command(dpu::DMACommand *dma_command); void service_output_q(); bool service_fr(); bool service_fcfs(); }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/memory_command.cc ================================================ #include "simulator/dram/memory_command.h" #include #include "abi/word/data_word.h" #include "util/config_loader.h" namespace upmem_sim::simulator::dram { MemoryCommand::MemoryCommand(Operation operation, Address address) : operation_(operation), address_(new abi::word::DataAddressWord()), size_(0), dma_command_(nullptr) { assert(operation == ACTIVATION or operation == PRECHARGE); assert(address >= util::ConfigLoader::mram_offset()); assert(address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); address_->set_value(address); } MemoryCommand::MemoryCommand(Operation operation, Address address, Address size, dpu::DMACommand *dma_command) : operation_(operation), address_(new abi::word::DataAddressWord()), size_(size), dma_command_(dma_command) { assert(operation == READ); assert(address >= util::ConfigLoader::mram_offset()); assert(address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(dma_command->operation() == dpu::DMACommand::Operation::READ); address_->set_value(address); } MemoryCommand::MemoryCommand(Operation operation, Address address, Address size, std::vector bytes, dpu::DMACommand *dma_command) : operation_(operation), address_(new abi::word::DataAddressWord()), size_(size), bytes_(bytes), dma_command_(dma_command) { assert(operation == WRITE); assert(address >= util::ConfigLoader::mram_offset()); assert(address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(dma_command->operation() == dpu::DMACommand::Operation::WRITE); address_->set_value(address); } MemoryCommand::~MemoryCommand() { delete address_; } std::vector MemoryCommand::bytes() { assert(operation_ == READ or operation_ == WRITE); return bytes_; } dpu::DMACommand *MemoryCommand::dma_command() { assert(dma_command_ != nullptr); return dma_command_; } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/memory_command.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_MEMORY_COMMAND_H_ #define UPMEM_SIM_SIMULATOR_DRAM_MEMORY_COMMAND_H_ #include "abi/word/data_address_word.h" #include "abi/word/data_word.h" #include "simulator/dpu/dma_command.h" namespace upmem_sim::simulator::dram { class MemoryCommand { public: enum Operation { ACTIVATION = 0, READ, WRITE, PRECHARGE, }; explicit MemoryCommand(Operation operation, Address address); explicit MemoryCommand(Operation operation, Address address, Address size, dpu::DMACommand *dma_command); explicit MemoryCommand(Operation operation, Address address, Address size, std::vector bytes, dpu::DMACommand *dma_command); ~MemoryCommand(); Operation operation() { return operation_; } Address address() { return address_->address(); } Address size() { return size_; } std::vector bytes(); void set_bytes(std::vector bytes) { bytes_ = bytes; } dpu::DMACommand *dma_command(); private: Operation operation_; abi::word::DataAddressWord *address_; Address size_; std::vector bytes_; dpu::DMACommand *dma_command_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/memory_controller.cc ================================================ #include "simulator/dram/memory_controller.h" #include "simulator/dram/fifo_scheduler.h" #include "simulator/dram/frfcfs_scheduler.h" namespace upmem_sim::simulator::dram { MemoryController::MemoryController(util::ArgumentParser *argument_parser) : wordline_size_(argument_parser->get_int_parameter("wordline_size")), row_buffer_(new RowBuffer(argument_parser)), mram_(nullptr), input_q_(new basic::Queue(-1)), wait_q_(new basic::Queue(-1)), memory_command_q_(new basic::Queue(1)), ready_q_(new basic::Queue(-1)), stat_factory_(new util::StatFactory("MemoryController")) { std::string memory_scheduling_policy = argument_parser->get_string_parameter("memory_scheduling_policy"); if (memory_scheduling_policy == "fifo") { scheduler_ = new FIFOScheduler(argument_parser); } else if (memory_scheduling_policy == "frfcfs") { scheduler_ = new FRFCFSScheduler(argument_parser); } else { throw std::invalid_argument(""); } } MemoryController::~MemoryController() { delete scheduler_; delete row_buffer_; delete input_q_; delete wait_q_; delete memory_command_q_; delete ready_q_; delete stat_factory_; } util::StatFactory *MemoryController::stat_factory() { auto stat_factory = new util::StatFactory(""); util::StatFactory *scheduler_stat_factory = scheduler_->stat_factory(); util::StatFactory *row_buffer_stat_factory = row_buffer_->stat_factory(); stat_factory->merge(stat_factory_); stat_factory->merge(scheduler_stat_factory); stat_factory->merge(row_buffer_stat_factory); delete scheduler_stat_factory; delete row_buffer_stat_factory; return stat_factory; } void MemoryController::connect_mram(MRAM *mram) { assert(mram != nullptr); assert(mram_ == nullptr); mram_ = mram; row_buffer_->connect_mram(mram); } void MemoryController::push(dpu::DMACommand *dma_command) { assert(dma_command != nullptr); input_q_->push(dma_command); } dpu::DMACommand *MemoryController::pop() { assert(can_pop()); return ready_q_->pop(); } dpu::DMACommand *MemoryController::front() { assert(can_pop()); return ready_q_->front(); } std::vector MemoryController::read(Address address, Address size) { Address end_address = address + size; Address cur_address = address; std::vector bytes; while (cur_address < end_address) { Address cur_wordline_address = (cur_address / wordline_size_) * wordline_size_; Address cur_size = std::min(cur_wordline_address + wordline_size_, end_address) - cur_address; int cur_offset = cur_address % wordline_size_; std::vector mram_bytes = mram_->read(cur_wordline_address); bytes.insert(bytes.end(), mram_bytes.begin() + cur_offset, mram_bytes.begin() + cur_offset + cur_size); cur_address += cur_size; } return std::move(bytes); } void MemoryController::write(Address address, Address size, std::vector bytes) { assert(bytes.size() == size); Address end_address = address + size; Address cur_address = address; int cur_bytes_offset = 0; while (cur_address < end_address) { Address cur_wordline_address = (cur_address / wordline_size_) * wordline_size_; Address cur_size = std::min(cur_wordline_address + wordline_size_, end_address) - cur_address; int cur_offset = cur_address % wordline_size_; std::vector mram_bytes = mram_->read(cur_wordline_address); std::copy(bytes.begin() + cur_bytes_offset, bytes.begin() + cur_bytes_offset + cur_size, mram_bytes.begin() + cur_offset); mram_->write(cur_wordline_address, mram_bytes); cur_address += cur_size; cur_bytes_offset += cur_size; } } void MemoryController::write(Address address, Address size, encoder::ByteStream *byte_stream) { assert(byte_stream->size() == size); std::vector bytes = byte_stream->bytes(); Address end_address = address + size; Address cur_address = address; int cur_bytes_offset = 0; while (cur_address < end_address) { Address cur_wordline_address = (cur_address / wordline_size_) * wordline_size_; Address cur_size = std::min(cur_wordline_address + wordline_size_, end_address) - cur_address; int cur_offset = cur_address % wordline_size_; std::vector mram_bytes = mram_->read(cur_wordline_address); std::copy(bytes.begin() + cur_bytes_offset, bytes.begin() + cur_bytes_offset + cur_size, mram_bytes.begin() + cur_offset); mram_->write(cur_wordline_address, mram_bytes); cur_address += cur_size; cur_bytes_offset += cur_size; } } void MemoryController::flush() { scheduler_->flush(); row_buffer_->flush(); } void MemoryController::cycle() { service_input_q(); service_scheduler(); service_memory_command_q(); service_row_buffer(); service_wait_q(); scheduler_->cycle(); row_buffer_->cycle(); stat_factory_->increment("mem_cycle"); } void MemoryController::service_input_q() { if (input_q_->can_pop() and scheduler_->can_push() and wait_q_->can_push()) { dpu::DMACommand *dma_command = input_q_->pop(); scheduler_->push(dma_command); wait_q_->push(dma_command); } } void MemoryController::service_scheduler() { if (scheduler_->can_pop() and memory_command_q_->can_push()) { MemoryCommand *memory_command = scheduler_->pop(); memory_command_q_->push(memory_command); } } void MemoryController::service_memory_command_q() { if (memory_command_q_->can_pop() and row_buffer_->can_push()) { MemoryCommand *memory_command = memory_command_q_->pop(); row_buffer_->push(memory_command); } } void MemoryController::service_row_buffer() { if (row_buffer_->can_pop()) { MemoryCommand *memory_command = row_buffer_->pop(); if (memory_command->operation() == MemoryCommand::ACTIVATION or memory_command->operation() == MemoryCommand::PRECHARGE) { delete memory_command; } else if (memory_command->operation() == MemoryCommand::READ) { memory_command->dma_command()->set_bytes(memory_command->address(), memory_command->size(), memory_command->bytes()); memory_command->dma_command()->ack_bytes(memory_command->address(), memory_command->size()); delete memory_command; } else if (memory_command->operation() == MemoryCommand::WRITE) { memory_command->dma_command()->ack_bytes(memory_command->address(), memory_command->size()); delete memory_command; } else { throw std::invalid_argument(""); } } } void MemoryController::service_wait_q() { if (not wait_q_->empty()) { dpu::DMACommand *dma_command = wait_q_->front(); if (dma_command->is_ready() and ready_q_->can_push()) { wait_q_->pop(); ready_q_->push(dma_command); } } } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/memory_controller.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_MEMORY_CONTROLLER_H_ #define UPMEM_SIM_SIMULATOR_DRAM_MEMORY_CONTROLLER_H_ #include "simulator/dram/mram.h" #include "simulator/dram/row_buffer.h" #include "simulator/dram/scheduler.h" namespace upmem_sim::simulator::dram { class MemoryController { public: explicit MemoryController(util::ArgumentParser *argument_parser); ~MemoryController(); util::StatFactory *stat_factory(); void connect_mram(MRAM *mram); bool empty() { return input_q_->empty() and wait_q_->empty() and memory_command_q_->empty() and ready_q_->empty() and scheduler_->empty() and row_buffer_->empty(); } bool can_push() { return input_q_->can_push(); } void push(dpu::DMACommand *dma_command); bool can_pop() { return ready_q_->can_pop(); } dpu::DMACommand *pop(); dpu::DMACommand *front(); std::vector read(Address address, Address size); void write(Address address, Address size, std::vector bytes); void write(Address address, Address size, encoder::ByteStream *byte_stream); void flush(); void cycle(); protected: void service_input_q(); void service_scheduler(); void service_memory_command_q(); void service_row_buffer(); void service_wait_q(); private: Address wordline_size_; Scheduler *scheduler_; RowBuffer *row_buffer_; MRAM *mram_; basic::Queue *input_q_; basic::Queue *wait_q_; basic::Queue *memory_command_q_; basic::Queue *ready_q_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/mram.cc ================================================ #include "simulator/dram/mram.h" namespace upmem_sim::simulator::dram { MRAM::MRAM(util::ArgumentParser *argument_parser) : address_(new abi::word::DataAddressWord()), size_(util::ConfigLoader::mram_size()) { address_->set_value(util::ConfigLoader::mram_offset()); wordline_size_ = argument_parser->get_int_parameter("wordline_size"); assert(wordline_size_ > 0); assert(wordline_size_ % util::ConfigLoader::min_access_granularity() == 0); assert(address() % wordline_size_ == 0); assert(size_ % wordline_size_ == 0); num_wordlines_ = static_cast(util::ConfigLoader::mram_size() / wordline_size_); wordlines_.resize(num_wordlines_); for (int i = 0; i < num_wordlines_; i++) { wordlines_[i] = new Wordline(argument_parser, address() + i * wordline_size_); } } MRAM::~MRAM() { delete address_; for (int i = 0; i < num_wordlines_; i++) { delete wordlines_[i]; } } std::vector MRAM::read(Address address) { return std::move(wordlines_[index(address)]->read()); } void MRAM::write(Address address, std::vector bytes) { wordlines_[index(address)]->write(std::move(bytes)); } void MRAM::write(Address address, encoder::ByteStream *byte_stream) { wordlines_[index(address)]->write(byte_stream); } int MRAM::index(Address address) { assert(address >= this->address()); assert(address + abi::word::DataWord().size() <= this->address() + size_); assert(address % wordline_size_ == 0); return static_cast((address - this->address()) / wordline_size_); } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/mram.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_MRAM_H_ #define UPMEM_SIM_SIMULATOR_DRAM_MRAM_H_ #include #include "abi/word/data_address_word.h" #include "simulator/dram/wordline.h" #include "util/argument_parser.h" namespace upmem_sim::simulator::dram { class MRAM { public: explicit MRAM(util::ArgumentParser *argument_parser); ~MRAM(); Address address() { return address_->address(); } Address size() { return size_; } std::vector read(Address address); void write(Address address, std::vector bytes); void write(Address address, encoder::ByteStream *byte_stream); void cycle() = delete; protected: int index(Address address); private: abi::word::DataAddressWord *address_; Address size_; std::vector wordlines_; Address wordline_size_; int num_wordlines_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/row_buffer.cc ================================================ #include "simulator/dram/row_buffer.h" namespace upmem_sim::simulator::dram { RowBuffer::RowBuffer(util::ArgumentParser *argument_parser) : mram_(nullptr), row_address_(nullptr), input_q_(new basic::Queue(1)), ready_q_(new basic::Queue(-1)), stat_factory_(new util::StatFactory("row_buffer")) { timing_parameters_["t_ras"] = static_cast(argument_parser->get_int_parameter("t_ras")); timing_parameters_["t_rcd"] = static_cast(argument_parser->get_int_parameter("t_rcd")); timing_parameters_["t_cl"] = static_cast(argument_parser->get_int_parameter("t_cl")); timing_parameters_["t_bl"] = static_cast(argument_parser->get_int_parameter("t_bl")); timing_parameters_["t_rp"] = static_cast(argument_parser->get_int_parameter("t_rp")); assert(timing_parameters_["t_ras"] > 0); assert(timing_parameters_["t_rcd"] > 0); assert(timing_parameters_["t_cl"] > 0); assert(timing_parameters_["t_bl"] > 0); assert(timing_parameters_["t_rp"] > 0); wordline_size_ = argument_parser->get_int_parameter("wordline_size"); assert(wordline_size_ > 0); activation_q_ = new basic::TimerQueue(1, timing_parameters_["t_ras"]); io_q_ = new basic::TimerQueue(1, timing_parameters_["t_cl"]); bus_q_ = new basic::TimerQueue(1, timing_parameters_["t_bl"]); precharge_q_ = new basic::TimerQueue(1, timing_parameters_["t_rp"]); } RowBuffer::~RowBuffer() { delete row_address_; delete input_q_; delete ready_q_; delete activation_q_; delete io_q_; delete bus_q_; delete precharge_q_; delete stat_factory_; } util::StatFactory *RowBuffer::stat_factory() { auto stat_factory = new util::StatFactory(""); stat_factory->merge(stat_factory_); return stat_factory; } void RowBuffer::connect_mram(MRAM *mram) { assert(mram != nullptr); assert(mram_ == nullptr); mram_ = mram; } void RowBuffer::push(MemoryCommand *memory_command) { assert(memory_command != nullptr); assert(can_push()); input_q_->push(memory_command); } MemoryCommand *RowBuffer::pop() { assert(can_pop()); return ready_q_->pop(); } void RowBuffer::flush() { if (row_address_ != nullptr) { write_to_mram(); delete row_address_; row_address_ = nullptr; } } void RowBuffer::cycle() { service_input_q(); service_activation_q(); service_io_q(); service_bus_q(); service_precharge_q(); activation_q_->cycle(); io_q_->cycle(); bus_q_->cycle(); precharge_q_->cycle(); } void RowBuffer::service_input_q() { if (input_q_->can_pop()) { MemoryCommand *memory_command = input_q_->front(); if (memory_command->operation() == MemoryCommand::ACTIVATION) { if (activation_q_->empty() and row_address_ == nullptr) { activation_q_->push(memory_command); input_q_->pop(); } } else if (memory_command->operation() == MemoryCommand::READ) { if (io_q_->can_push() and row_address_ != nullptr) { io_q_->push(memory_command); input_q_->pop(); } } else if (memory_command->operation() == MemoryCommand::WRITE) { if (io_q_->can_push() and row_address_ != nullptr) { io_q_->push(memory_command); input_q_->pop(); } } else if (memory_command->operation() == MemoryCommand::PRECHARGE) { if (activation_q_->empty() and io_q_->empty() and bus_q_->empty() and precharge_q_->empty()) { precharge_q_->push(memory_command); input_q_->pop(); } } else { throw std::invalid_argument(""); } } } void RowBuffer::service_activation_q() { auto [memory_command, cycle] = activation_q_->front(); if (cycle == timing_parameters_["t_ras"] - timing_parameters_["t_rcd"]) { assert(row_address_ == nullptr); assert(memory_command->address() % wordline_size_ == 0); row_address_ = new abi::word::DataAddressWord(); row_address_->set_value(memory_command->address()); row_buffer_ = read_from_mram(); } if (activation_q_->can_pop() and ready_q_->can_push()) { activation_q_->pop(); ready_q_->push(memory_command); stat_factory_->increment("num_activations"); } } void RowBuffer::service_io_q() { if (io_q_->can_pop() and bus_q_->can_push()) { MemoryCommand *memory_command = io_q_->pop(); bus_q_->push(memory_command); } } void RowBuffer::service_bus_q() { if (bus_q_->can_pop() and ready_q_->can_push()) { MemoryCommand *memory_command = bus_q_->pop(); ready_q_->push(memory_command); if (memory_command->operation() == MemoryCommand::READ) { std::vector bytes = read_from_row_buffer(memory_command->address(), memory_command->size()); memory_command->set_bytes(bytes); stat_factory_->increment("num_reads"); if (memory_command->dma_command()->has_instruction()) { stat_factory_->increment( std::to_string( memory_command->dma_command()->instruction()->thread()->id()) + "_num_reads"); } stat_factory_->increment("read_bytes", memory_command->size()); if (memory_command->dma_command()->has_instruction()) { stat_factory_->increment( std::to_string( memory_command->dma_command()->instruction()->thread()->id()) + "_read_bytes", memory_command->size()); } } else if (memory_command->operation() == MemoryCommand::WRITE) { write_to_row_buffer(memory_command->address(), memory_command->size(), memory_command->bytes()); stat_factory_->increment("num_writes"); if (memory_command->dma_command()->has_instruction()) { stat_factory_->increment( std::to_string( memory_command->dma_command()->instruction()->thread()->id()) + "_num_writes"); } stat_factory_->increment("write_bytes", memory_command->size()); if (memory_command->dma_command()->has_instruction()) { stat_factory_->increment( std::to_string( memory_command->dma_command()->instruction()->thread()->id()) + "_write_bytes", memory_command->size()); } } else { throw std::invalid_argument(""); } } } void RowBuffer::service_precharge_q() { if (precharge_q_->can_pop() and ready_q_->can_push()) { MemoryCommand *memory_command = precharge_q_->pop(); assert(memory_command->address() % wordline_size_ == 0); assert(memory_command->address() == row_address_->address()); write_to_mram(); delete row_address_; row_address_ = nullptr; ready_q_->push(memory_command); stat_factory_->increment("num_precharges"); } } std::vector RowBuffer::read_from_mram() { assert(row_address_ != nullptr); return std::move(mram_->read(row_address_->address())); } std::vector RowBuffer::read_from_row_buffer(Address address, Address size) { assert(row_address_ != nullptr); std::vector bytes; bytes.resize(size); std::copy(row_buffer_.begin() + index(address), row_buffer_.begin() + index(address + size), bytes.begin()); return std::move(bytes); } void RowBuffer::write_to_mram() { assert(row_address_ != nullptr); mram_->write(row_address_->address(), std::move(row_buffer_)); } void RowBuffer::write_to_row_buffer(Address address, Address size, std::vector bytes) { assert(size == bytes.size()); std::copy(bytes.begin(), bytes.end(), row_buffer_.begin() + index(address)); } int RowBuffer::index(Address address) { assert(row_address_->address() <= address and address <= row_address_->address() + wordline_size_); return static_cast(address - row_address_->address()); } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/row_buffer.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_ROW_BUFFER_H_ #define UPMEM_SIM_SIMULATOR_DRAM_ROW_BUFFER_H_ #include #include #include "simulator/basic/queue.h" #include "simulator/basic/timer_queue.h" #include "simulator/dram/memory_command.h" #include "simulator/dram/mram.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dram { class RowBuffer { public: explicit RowBuffer(util::ArgumentParser *argument_parser); ~RowBuffer(); util::StatFactory *stat_factory(); void connect_mram(MRAM *mram); bool empty() { return input_q_->empty() and ready_q_->empty() and activation_q_->empty() and io_q_->empty() and bus_q_->empty() and precharge_q_->empty(); } bool can_push() { return input_q_->can_push(); } void push(MemoryCommand *memory_command); bool can_pop() { return ready_q_->can_pop(); } MemoryCommand *pop(); void flush(); void cycle(); protected: void service_input_q(); void service_activation_q(); void service_io_q(); void service_bus_q(); void service_precharge_q(); std::vector read_from_mram(); std::vector read_from_row_buffer(Address address, Address size); void write_to_mram(); void write_to_row_buffer(Address address, Address size, std::vector bytes); int index(Address address); private: std::map timing_parameters_; Address wordline_size_; MRAM *mram_; abi::word::DataAddressWord *row_address_; std::vector row_buffer_; basic::Queue *input_q_; basic::Queue *ready_q_; basic::TimerQueue *activation_q_; basic::TimerQueue *io_q_; basic::TimerQueue *bus_q_; basic::TimerQueue *precharge_q_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/scheduler.cc ================================================ #include "simulator/dram/scheduler.h" namespace upmem_sim::simulator::dram { Scheduler::Scheduler(util::ArgumentParser *argument_parser) : input_q_(new basic::Queue(-1)), ready_q_(new basic::Queue(3)), row_address_(nullptr), stat_factory_(new util::StatFactory("Scheduler")) { wordline_size_ = argument_parser->get_int_parameter("wordline_size"); assert(wordline_size_ > 0); assert(wordline_size_ % util::ConfigLoader::min_access_granularity() == 0); } Scheduler::~Scheduler() { delete input_q_; delete ready_q_; delete row_address_; delete stat_factory_; } util::StatFactory *Scheduler::stat_factory() { auto stat_factory = new util::StatFactory(""); stat_factory->merge(stat_factory_); return stat_factory; } void Scheduler::push(dpu::DMACommand *dma_command) { assert(dma_command != nullptr); input_q_->push(dma_command); } MemoryCommand *Scheduler::pop() { assert(can_pop()); return ready_q_->pop(); } void Scheduler::flush() { delete row_address_; row_address_ = nullptr; } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/scheduler.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_SCHEDULER_H_ #define UPMEM_SIM_SIMULATOR_DRAM_SCHEDULER_H_ #include "simulator/basic/queue.h" #include "simulator/dpu/dma_command.h" #include "simulator/dram/memory_command.h" #include "util/argument_parser.h" #include "util/stat_factory.h" namespace upmem_sim::simulator::dram { class Scheduler { public: using MemoryReference = std::tuple; explicit Scheduler(util::ArgumentParser *argument_parser); ~Scheduler(); util::StatFactory *stat_factory(); bool empty() { return input_q_->empty() and ready_q_->empty() and reorder_buffer_.empty(); } bool can_push() { return input_q_->can_push(); } void push(dpu::DMACommand *dma_command); bool can_pop() { return ready_q_->can_pop(); } MemoryCommand *pop(); void flush(); virtual void cycle() = 0; protected: basic::Queue *input_q_; basic::Queue *ready_q_; abi::word::DataAddressWord *row_address_; std::vector reorder_buffer_; Address wordline_size_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/wordline.cc ================================================ #include "simulator/dram/wordline.h" namespace upmem_sim::simulator::dram { Wordline::Wordline(util::ArgumentParser *argument_parser, Address address) : address_(new abi::word::DataAddressWord()), size_(argument_parser->get_int_parameter("wordline_size")) { assert(address >= util::ConfigLoader::mram_offset()); assert(address + size_ <= util::ConfigLoader::mram_offset() + util::ConfigLoader::mram_size()); assert(address % size_ == 0); assert(size_ % util::ConfigLoader::min_access_granularity() == 0); assert(size_ % abi::word::DataWord().size() == 0); address_->set_value(address); data_words_.resize(num_data_words()); for (int i = 0; i < num_data_words(); i++) { data_words_[i] = new abi::word::DataWord(); } } Wordline::~Wordline() { delete address_; for (int i = 0; i < num_data_words(); i++) { delete data_words_[i]; } } std::vector Wordline::read() { auto byte_stream = new encoder::ByteStream(); for (int i = 0; i < num_data_words(); i++) { auto data_word_byte_stream = data_words_[i]->to_byte_stream(); byte_stream->merge(data_word_byte_stream); delete data_word_byte_stream; } std::vector bytes = byte_stream->bytes(); delete byte_stream; return std::move(bytes); } void Wordline::write(std::vector bytes) { assert(bytes.size() == size_); Address data_word_size = abi::word::DataWord().size(); for (int i = 0; i < num_data_words(); i++) { for (int j = 0; j < data_word_size; j++) { int index = static_cast(i * data_word_size + j); data_words_[i]->set_bit_slice(8 * j, 8 * (j + 1), bytes[index]); } } } void Wordline::write(encoder::ByteStream *byte_stream) { assert(byte_stream->size() == size_); for (int i = 0; i < num_data_words(); i++) { encoder::ByteStream *slice = byte_stream->slice(8 * i, 8 * (i + 1)); data_words_[i]->from_byte_stream(slice); delete slice; } } } // namespace upmem_sim::simulator::dram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/dram/wordline.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_DRAM_WORDLINE_H_ #define UPMEM_SIM_SIMULATOR_DRAM_WORDLINE_H_ #include #include "abi/word/data_address_word.h" #include "abi/word/data_word.h" #include "util/argument_parser.h" namespace upmem_sim::simulator::dram { class Wordline { public: explicit Wordline(util::ArgumentParser *argument_parser, Address address); ~Wordline(); Address address() { return address_->address(); } Address size() { return size_; } std::vector read(); void write(std::vector bytes); void write(encoder::ByteStream *byte_stream); void cycle() = delete; protected: int num_data_words() { return static_cast(size_ / abi::word::DataWord().size()); } private: abi::word::DataAddressWord *address_; Address size_; std::vector data_words_; }; } // namespace upmem_sim::simulator::dram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/rank/rank.cc ================================================ #include "simulator/rank/rank.h" namespace upmem_sim::simulator::rank { Rank::Rank(util::ArgumentParser* argument_parser) : read_bandwidth_( argument_parser->get_int_parameter("rank_read_bandwidth")), write_bandwidth_( argument_parser->get_int_parameter("rank_write_bandwidth")), stat_factory_(new util::StatFactory("Rank")) { assert(read_bandwidth_ > 0); assert(write_bandwidth_ > 0); int num_dpus = static_cast(argument_parser->get_int_parameter("num_dpus")); dpus_.resize(num_dpus); communication_qs_.resize(num_dpus); for (DPUID dpu_id = 0; dpu_id < num_dpus; dpu_id++) { dpus_[dpu_id] = new dpu::DPU(dpu_id, argument_parser); communication_qs_[dpu_id] = new basic::TimerQueue(-1); } } Rank::~Rank() { for (auto& dpu : dpus_) { delete dpu; } for (auto & communication_q : communication_qs_) { delete communication_q; } delete stat_factory_; } util::StatFactory* Rank::stat_factory() { auto stat_factory = new util::StatFactory(""); stat_factory->merge(stat_factory_); for (auto& dpu : dpus_) { util::StatFactory* dpu_stat_factory = dpu->stat_factory(); stat_factory->merge(dpu_stat_factory); delete dpu_stat_factory; } return stat_factory; } void Rank::launch() { for (auto& dpu : dpus_) { for (auto& thread : dpu->scheduler()->threads()) { Address bootstrap = util::ConfigLoader::iram_offset(); thread->reg_file()->write_pc_reg(bootstrap); } dpu->boot(); } } bool Rank::is_zombie() { for (auto& dpu : dpus_) { if (not dpu->is_zombie()) { return false; } } return true; } void Rank::read(upmem_sim::simulator::rank::RankMessage*rank_message) { assert(rank_message->operation() == RankMessage::READ); assert(0 <= rank_message->dpu_id() and rank_message->dpu_id() < dpus_.size()); basic::TimerQueue* communication_q = communication_qs_[rank_message->dpu_id()]; assert(communication_q->can_push()); SimTime latency = static_cast(10 * rank_message->size() / read_bandwidth_); communication_q->push(rank_message, latency); stat_factory_->increment("num_reads"); stat_factory_->increment("read_bytes", rank_message->size()); } void Rank::write(RankMessage*rank_message) { assert(rank_message->operation() == RankMessage::WRITE); assert(0 <= rank_message->dpu_id() and rank_message->dpu_id() < dpus_.size()); basic::TimerQueue* communication_q = communication_qs_[rank_message->dpu_id()]; assert(communication_q->can_push()); SimTime latency = static_cast(10 * rank_message->size() / write_bandwidth_); communication_q->push(rank_message, latency); stat_factory_->increment("num_writes"); stat_factory_->increment("write_bytes", rank_message->size()); } void Rank::cycle() { service_sequence_q(); for (auto& dpu : dpus_) { dpu->cycle(); } bool is_communication_q_empty = true; for (auto & communication_q : communication_qs_) { communication_q->cycle(); if (not communication_q->empty()) { is_communication_q_empty = false; } } if (not is_communication_q_empty) { stat_factory_->increment("communication_cycle"); } stat_factory_->increment("rank_cycle"); } void Rank::service_sequence_q() { for (auto &communication_q : communication_qs_) { if (communication_q->can_pop()) { RankMessage * rank_message = communication_q->pop(); rank_message->set_ack(); } } } } // namespace upmem_sim::simulator::rank ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/rank/rank.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_RANK_RANK_H_ #define UPMEM_SIM_SIMULATOR_RANK_RANK_H_ #include #include "main.h" #include "simulator/basic/timer_queue.h" #include "simulator/dpu/dpu.h" #include "simulator/rank/rank_message.h" namespace upmem_sim::simulator::rank { class Rank { public: explicit Rank(util::ArgumentParser *argument_parser); ~Rank(); util::StatFactory *stat_factory(); std::vector dpus() { return dpus_; } void launch(); bool is_zombie(); void read(RankMessage *rank_message); void write(RankMessage *rank_message); void cycle(); protected: void service_sequence_q(); private: Address read_bandwidth_; Address write_bandwidth_; std::vector dpus_; std::vector*> communication_qs_; util::StatFactory *stat_factory_; }; } // namespace upmem_sim::simulator::rank #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/rank/rank_message.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_RANK_SEQUENCE_MESSAGE_H_ #define UPMEM_SIM_SIMULATOR_RANK_SEQUENCE_MESSAGE_H_ #include "encoder/byte_stream.h" #include "main.h" namespace upmem_sim::simulator::rank { class RankMessage { public: enum Operation { READ = 0, WRITE }; explicit RankMessage(Operation operation, DPUID dpu_id, Address address, Address size) : operation_(operation), dpu_id_(dpu_id), address_(address), size_(size), ack_(false) {} explicit RankMessage(Operation operation, DPUID dpu_id, Address address, Address size, encoder::ByteStream* byte_stream) : operation_(operation), dpu_id_(dpu_id), address_(address), size_(size), byte_stream_(byte_stream), ack_(false) { assert(byte_stream->size() == size); } ~RankMessage() = default; Operation operation() { return operation_; } DPUID dpu_id() { return dpu_id_; } Address address() { return address_; } Address size() { return size_; } encoder::ByteStream* byte_stream() { return byte_stream_; } bool ack() { return ack_; } void set_ack() { assert(not ack_); ack_ = true; } private: Operation operation_; DPUID dpu_id_; Address address_; Address size_; encoder::ByteStream* byte_stream_; bool ack_; }; } // namespace upmem_sim::simulator::rank #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/condition_reg.cc ================================================ #include "simulator/reg/condition_reg.h" #include namespace upmem_sim::simulator::reg { bool ConditionReg::condition(abi::isa::Condition condition) { if (condition == abi::isa::TRUE) { return true; } else if (condition == abi::isa::FALSE) { return false; } else { return bits_[condition]; } } void ConditionReg::set_condition(abi::isa::Condition condition) { assert(condition != abi::isa::TRUE and condition != abi::isa::FALSE); bits_[condition] = true; } void ConditionReg::clear_condition(abi::isa::Condition condition) { assert(condition != abi::isa::TRUE and condition != abi::isa::FALSE); bits_[condition] = false; } void ConditionReg::clear_conditions() { for (abi::isa::Condition condition = abi::isa::TRUE; condition <= abi::isa::LARGE; condition = static_cast(condition + 1)) { if (condition == abi::isa::TRUE or condition == abi::isa::FALSE) { continue; } else { clear_condition(condition); } } } } // namespace upmem_sim::simulator::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/condition_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_CONDITION_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_CONDITION_REG_H_ #include #include "abi/isa/condition.h" namespace upmem_sim::simulator::reg { class ConditionReg { public: explicit ConditionReg() { bits_.resize(abi::isa::LARGE + 1); } ~ConditionReg() = default; bool condition(abi::isa::Condition condition); void set_condition(abi::isa::Condition condition); void clear_condition(abi::isa::Condition condition); void clear_conditions(); void cycle() = delete; private: std::vector bits_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/exception_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_EXCEPTION_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_EXCEPTION_REG_H_ #include #include "abi/isa/exception.h" namespace upmem_sim::simulator::reg { class ExceptionReg { public: explicit ExceptionReg() { bits_.resize(abi::isa::NOT_PROFILING + 1); } ~ExceptionReg() = default; bool exception(abi::isa::Exception exception) { return bits_[exception]; } void set_exception(abi::isa::Exception exception) { bits_[exception] = true; } void clear_exception(abi::isa::Exception exception) { bits_[exception] = false; } void cycle() = delete; private: std::vector bits_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/flag_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_FLAG_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_FLAG_REG_H_ #include #include "abi/isa/flag.h" namespace upmem_sim::simulator::reg { class FlagReg { public: explicit FlagReg() { bits_.resize(abi::isa::CARRY + 1); } ~FlagReg() = default; bool flag(abi::isa::Flag flag) { return bits_[flag]; } void set_flag(abi::isa::Flag flag) { bits_[flag] = true; } void clear_flag(abi::isa::Flag flag) { bits_[flag] = false; } void cycle() = delete; private: std::vector bits_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/gp_reg.cc ================================================ #include "simulator/reg/gp_reg.h" namespace upmem_sim::simulator::reg { GPReg::~GPReg() { delete gp_reg_; delete word_; } } // namespace upmem_sim::simulator::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/gp_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_GP_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_GP_REG_H_ #include "abi/reg/gp_reg.h" #include "abi/word/data_word.h" namespace upmem_sim::simulator::reg { class GPReg { public: explicit GPReg(RegIndex index) : gp_reg_(new abi::reg::GPReg(index)), word_(new abi::word::DataWord()) {} ~GPReg(); RegIndex index() { return gp_reg_->index(); } int64_t read(abi::word::Representation representation) { return word_->value(representation); } void write(int64_t value) { word_->set_value(value); } void cycle() = delete; private: abi::reg::GPReg *gp_reg_; abi::word::DataWord *word_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/pc_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_PC_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_PC_REG_H_ #include "abi/word/instruction_address_word.h" #include "abi/word/instruction_word.h" namespace upmem_sim::simulator::reg { class PCReg { public: explicit PCReg() : word_(new abi::word::InstructionAddressWord()) {} ~PCReg() { delete word_; } int64_t read() { return word_->address(); } void write(int64_t value) { word_->set_value(value); } void increment() { write(read() + abi::word::InstructionWord().size()); } void cycle() = delete; private: abi::word::InstructionAddressWord *word_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/reg_file.cc ================================================ #include "simulator/reg/reg_file.h" #include #include namespace upmem_sim::simulator::reg { RegFile::RegFile(ThreadID id) : sp_reg_(new SPReg(id)), pc_reg_(new PCReg()), condition_reg_(new ConditionReg()), flag_reg_(new FlagReg()), exception_reg_(new ExceptionReg()) { for (RegIndex index = 0; index < util::ConfigLoader::num_gp_registers(); index++) { gp_regs_.push_back(new GPReg(index)); } } RegFile::~RegFile() { for (RegIndex index = 0; index < util::ConfigLoader::num_gp_registers(); index++) { delete gp_regs_[index]; } delete sp_reg_; delete pc_reg_; delete condition_reg_; delete flag_reg_; delete exception_reg_; } std::tuple RegFile::read_pair_reg( abi::reg::PairReg *pair_reg, abi::word::Representation representation) { int64_t even = read_gp_reg(pair_reg->even_reg(), representation); int64_t odd = read_gp_reg(pair_reg->odd_reg(), abi::word::UNSIGNED); return {even, odd}; } int64_t RegFile::read_src_reg(abi::reg::SrcReg *src_reg, abi::word::Representation representation) { if (src_reg->is_gp_reg()) { return read_gp_reg(src_reg->gp_reg(), representation); } else { return read_sp_reg(*src_reg->sp_reg(), representation); } } void RegFile::write_pair_reg(abi::reg::PairReg *pair_reg, int64_t even, int64_t odd) { write_gp_reg(pair_reg->even_reg(), even); write_gp_reg(pair_reg->odd_reg(), odd); } } // namespace upmem_sim::simulator::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/reg_file.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_REG_FILE_H_ #define UPMEM_SIM_SIMULATOR_REG_REG_FILE_H_ #include "abi/reg/pair_reg.h" #include "abi/reg/src_reg.h" #include "simulator/reg/condition_reg.h" #include "simulator/reg/exception_reg.h" #include "simulator/reg/flag_reg.h" #include "simulator/reg/gp_reg.h" #include "simulator/reg/pc_reg.h" #include "simulator/reg/sp_reg.h" namespace upmem_sim::simulator::reg { class RegFile { public: explicit RegFile(ThreadID id); ~RegFile(); int64_t read_gp_reg(abi::reg::GPReg *gp_reg, abi::word::Representation representation) { return gp_regs_[gp_reg->index()]->read(representation); } int64_t read_sp_reg(abi::reg::SPReg sp_reg, abi::word::Representation representation) { return sp_reg_->read(sp_reg, representation); } std::tuple read_pair_reg( abi::reg::PairReg *pair_reg, abi::word::Representation representation); int64_t read_src_reg(abi::reg::SrcReg *src_reg, abi::word::Representation representation); int64_t read_pc_reg() { return pc_reg_->read(); } bool condition(abi::isa::Condition condition) { return condition_reg_->condition(condition); } bool flag(abi::isa::Flag flag) { return flag_reg_->flag(flag); } bool exception(abi::isa::Exception exception) { return exception_reg_->exception(exception); } void write_gp_reg(abi::reg::GPReg *gp_reg, int64_t value) { gp_regs_[gp_reg->index()]->write(value); } void write_pair_reg(abi::reg::PairReg *pair_reg, int64_t even, int64_t odd); void write_pc_reg(int64_t value) { pc_reg_->write(value); } void increment_pc_reg() { pc_reg_->increment(); } void set_condition(abi::isa::Condition condition) { condition_reg_->set_condition(condition); } void clear_condition(abi::isa::Condition condition) { condition_reg_->clear_condition(condition); } void clear_conditions() { condition_reg_->clear_conditions(); } void set_flag(abi::isa::Flag flag) { flag_reg_->set_flag(flag); } void clear_flag(abi::isa::Flag flag) { flag_reg_->clear_flag(flag); } void set_exception(abi::isa::Exception exception) { exception_reg_->set_exception(exception); } void clear_exception(abi::isa::Exception exception) { exception_reg_->clear_exception(exception); } void cycle() = delete; private: std::vector gp_regs_; SPReg *sp_reg_; PCReg *pc_reg_; ConditionReg *condition_reg_; FlagReg *flag_reg_; ExceptionReg *exception_reg_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/sp_reg.cc ================================================ #include "simulator/reg/sp_reg.h" #include namespace upmem_sim::simulator::reg { SPReg::SPReg(ThreadID id) : zero_(new abi::word::DataWord()), one_(new abi::word::DataWord()), lneg_(new abi::word::DataWord()), mneg_(new abi::word::DataWord()), id_(new abi::word::DataWord()), id2_(new abi::word::DataWord()), id4_(new abi::word::DataWord()), id8_(new abi::word::DataWord()) { zero_->set_value(0); one_->set_value(1); lneg_->set_value(-1); mneg_->set_bit(mneg_->width() - 1); id_->set_value(id); id2_->set_value(2 * id); id4_->set_value(4 * id); id8_->set_value(8 * id); } SPReg::~SPReg() { delete zero_; delete one_; delete lneg_; delete mneg_; delete id_; delete id2_; delete id4_; delete id8_; } int64_t SPReg::read(abi::reg::SPReg sp_reg, abi::word::Representation representation) { if (sp_reg == abi::reg::ZERO) { return zero_->value(representation); } else if (sp_reg == abi::reg::ONE) { return one_->value(representation); } else if (sp_reg == abi::reg::LNEG) { return lneg_->value(representation); } else if (sp_reg == abi::reg::MNEG) { return mneg_->value(representation); } else if (sp_reg == abi::reg::ID) { return id_->value(representation); } else if (sp_reg == abi::reg::ID2) { return id2_->value(representation); } else if (sp_reg == abi::reg::ID4) { return id4_->value(representation); } else if (sp_reg == abi::reg::ID8) { return id8_->value(representation); } else { throw std::invalid_argument(""); } } } // namespace upmem_sim::simulator::reg ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/reg/sp_reg.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_REG_SP_REG_H_ #define UPMEM_SIM_SIMULATOR_REG_SP_REG_H_ #include "abi/reg/sp_reg.h" #include "abi/word/data_word.h" namespace upmem_sim::simulator::reg { class SPReg { public: explicit SPReg(ThreadID id); ~SPReg(); int64_t read(abi::reg::SPReg sp_reg, abi::word::Representation representation); void cycle() = delete; private: abi::word::DataWord *zero_; abi::word::DataWord *one_; abi::word::DataWord *lneg_; abi::word::DataWord *mneg_; abi::word::DataWord *id_; abi::word::DataWord *id2_; abi::word::DataWord *id4_; abi::word::DataWord *id8_; }; } // namespace upmem_sim::simulator::reg #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/atomic.cc ================================================ #include "simulator/sram/atomic.h" namespace upmem_sim::simulator::sram { Atomic::Atomic() { address_ = new abi::word::DataAddressWord(); address_->set_value(util::ConfigLoader::atomic_offset()); size_ = util::ConfigLoader::atomic_size(); locks_.resize(size_); for (int i = 0; i < size_; i++) { locks_[i] = new Lock(); } } Atomic::~Atomic() { delete address_; for (int i = 0; i < size_; i++) { delete locks_[i]; } } int Atomic::index(Address address) { assert(address >= this->address()); assert(address < this->address() + size_); assert(this->address() <= address and address < this->address() + size_); return static_cast(address - this->address()); } } // namespace upmem_sim::simulator::sram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/atomic.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_SRAM_ATOMIC_H_ #define UPMEM_SIM_SIMULATOR_SRAM_ATOMIC_H_ #include #include "abi/word/data_address_word.h" #include "simulator/sram/lock.h" #include "util/config_loader.h" namespace upmem_sim::simulator::sram { class Atomic { public: explicit Atomic(); ~Atomic(); Address address() { return address_->address(); } Address size() { return size_; } bool can_acquire(Address address) { return locks_[index(address)]->can_acquire(); } void acquire(Address address, ThreadID id) { locks_[index(address)]->acquire(id); } bool can_release(Address address, ThreadID id) { return locks_[index(address)]->can_release(id); } void release(Address address, ThreadID id) { locks_[index(address)]->release(id); } void cycle() = delete; protected: int index(Address address); private: abi::word::DataAddressWord *address_; Address size_; std::vector locks_; }; } // namespace upmem_sim::simulator::sram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/iram.cc ================================================ #include "simulator/sram/iram.h" #include "encoder/instruction_encoder.h" namespace upmem_sim::simulator::sram { IRAM::IRAM() { address_ = new abi::word::InstructionAddressWord(); address_->set_value(util::ConfigLoader::iram_offset()); size_ = util::ConfigLoader::iram_size(); assert(address() % abi::word::InstructionWord().size() == 0); assert(size_ % abi::word::InstructionWord().size() == 0); cells_.resize(num_instruction_words()); for (int i = 0; i < num_instruction_words(); i++) { cells_[i] = new abi::word::InstructionWord(); } } IRAM::~IRAM() { delete address_; for (int i = 0; i < size_ / num_instruction_words(); i++) { delete cells_[i]; } } abi::instruction::Instruction *IRAM::read(Address address) { encoder::ByteStream *byte_stream = cells_[index(address)]->to_byte_stream(); abi::instruction::Instruction *instruction = encoder::InstructionEncoder::decode(byte_stream); delete byte_stream; return instruction; } void IRAM::write(Address address, encoder::ByteStream *byte_stream) { cells_[index(address)]->from_byte_stream(byte_stream); } int IRAM::index(Address address) { assert(address >= this->address()); assert(address + abi::word::InstructionWord().size() <= this->address() + size_); assert((address - this->address()) % abi::word::InstructionWord().size() == 0); return static_cast((address - this->address()) / abi::word::InstructionWord().size()); } } // namespace upmem_sim::simulator::sram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/iram.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_SRAM_IRAM_H_ #define UPMEM_SIM_SIMULATOR_SRAM_IRAM_H_ #include "abi/instruction/instruction.h" #include "abi/word/instruction_address_word.h" #include "abi/word/instruction_word.h" namespace upmem_sim::simulator::sram { class IRAM { public: explicit IRAM(); ~IRAM(); Address address() { return address_->address(); } Address size() { return size_; } abi::instruction::Instruction *read(Address address); void write(Address address, encoder::ByteStream *byte_stream); void cycle() = delete; protected: static int num_instruction_words() { return static_cast(util::ConfigLoader::iram_size() / abi::word::InstructionWord().size()); } int index(Address address); private: abi::word::InstructionAddressWord *address_; Address size_; std::vector cells_; }; } // namespace upmem_sim::simulator::sram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/lock.cc ================================================ #include "simulator/sram/lock.h" namespace upmem_sim::simulator::sram { void Lock::acquire(ThreadID id) { assert(can_acquire()); id_ = new ThreadID(id); } void Lock::release(ThreadID id) { assert(can_release(id)); delete id_; id_ = nullptr; } } // namespace upmem_sim::simulator::sram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/lock.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_SRAM_LOCK_H_ #define UPMEM_SIM_SIMULATOR_SRAM_LOCK_H_ #include #include "main.h" namespace upmem_sim::simulator::sram { class Lock { public: explicit Lock() : id_(nullptr) {} ~Lock() { assert(id_ == nullptr); } bool can_acquire() { return id_ == nullptr; } void acquire(ThreadID id); bool can_release(ThreadID id) { return id_ == nullptr or *id_ == id; } void release(ThreadID id); void cycle() = delete; private: ThreadID *id_; }; } // namespace upmem_sim::simulator::sram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/wram.cc ================================================ #include "simulator/sram/wram.h" namespace upmem_sim::simulator::sram { WRAM::WRAM() { address_ = new abi::word::DataAddressWord(); address_->set_value(util::ConfigLoader::wram_offset()); size_ = util::ConfigLoader::wram_size(); assert(address() % abi::word::DataWord().size() == 0); assert(size_ % abi::word::DataWord().size() == 0); cells_.resize(num_data_words()); for (int i = 0; i < num_data_words(); i++) { cells_[i] = new abi::word::DataWord(); } } WRAM::~WRAM() { delete address_; for (int i = 0; i < num_data_words(); i++) { delete cells_[i]; } } int64_t WRAM::read(Address address) { return cells_[index(address)]->value(abi::word::UNSIGNED); } void WRAM::write(Address address, int64_t value) { cells_[index(address)]->set_value(value); } void WRAM::write(Address address, encoder::ByteStream *byte_stream) { cells_[index(address)]->from_byte_stream(byte_stream); } int WRAM::index(Address address) { assert(address >= this->address()); assert(address + abi::word::DataWord().size() <= this->address() + size_); assert((address - this->address()) % abi::word::DataWord().size() == 0); return static_cast((address - this->address()) / abi::word::DataWord().size()); } } // namespace upmem_sim::simulator::sram ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/sram/wram.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_SRAM_WRAM_H_ #define UPMEM_SIM_SIMULATOR_SRAM_WRAM_H_ #include "abi/word/data_address_word.h" #include "abi/word/data_word.h" namespace upmem_sim::simulator::sram { class WRAM { public: explicit WRAM(); ~WRAM(); Address address() { return address_->address(); } Address size() { return size_; } int64_t read(Address address); void write(Address address, int64_t value); void write(Address address, encoder::ByteStream *byte_stream); void cycle() = delete; protected: static int num_data_words() { return static_cast(util::ConfigLoader::wram_size() / abi::word::DataWord().size()); } int index(Address address); private: abi::word::DataAddressWord *address_; Address size_; std::vector cells_; }; } // namespace upmem_sim::simulator::sram #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/system.cc ================================================ #include "simulator/system.h" namespace upmem_sim::simulator { System::System(util::ArgumentParser *argument_parser) : cpu_(new cpu::CPU(argument_parser)), rank_(new rank::Rank(argument_parser)), execuion_(0), stat_factory_(new util::StatFactory("System")) { benchmark = argument_parser->get_string_parameter("benchmark"); cpu_->connect_rank(rank_); } System::~System() { delete cpu_; delete rank_; delete stat_factory_; } util::StatFactory *System::stat_factory() { auto stat_factory = new util::StatFactory(""); util::StatFactory *rank_stat_factory = rank_->stat_factory(); stat_factory->merge(stat_factory_); stat_factory->merge(rank_stat_factory); delete rank_stat_factory; return stat_factory; } void System::init() { cpu_->init(); cpu_->sched(execuion_); cpu_->launch(); } void System::cycle() { cpu_->cycle(); rank_->cycle(); if (is_zombie()) { cpu_->check(execuion_); execuion_ += 1; if (not is_finished()) { if(benchmark == "TRNS"){ cpu_->init(); } cpu_->sched(execuion_); cpu_->launch(); } } } } // namespace upmem_sim::simulator ================================================ FILE: python_cpp/uPIMulator_backend/src/simulator/system.h ================================================ #ifndef UPMEM_SIM_SIMULATOR_SYSTEM_H_ #define UPMEM_SIM_SIMULATOR_SYSTEM_H_ #include "simulator/cpu/cpu.h" #include "simulator/dpu/dpu.h" #include "simulator/rank/rank.h" namespace upmem_sim::simulator { class System { public: explicit System(util::ArgumentParser *argument_parser); ~System(); util::StatFactory *stat_factory(); bool is_finished() { return execuion_ == cpu_->num_executions(); } void init(); void fini() { cpu_->fini(); } void cycle(); protected: bool is_zombie() { return rank_->is_zombie(); } private: cpu::CPU *cpu_; rank::Rank *rank_; int execuion_; util::StatFactory *stat_factory_; // Tae std::string benchmark; }; } // namespace upmem_sim::simulator #endif ================================================ FILE: python_cpp/uPIMulator_backend/src/util/argument_parser.cc ================================================ #include "util/argument_parser.h" #include namespace upmem_sim::util { void ArgumentParser::add_option(Option option, OptionType option_type, Parameter default_parameter) { assert(not option_types_.count(option)); assert(not default_parameters_.count(option)); assert(not custom_parameters_.count(option)); option_types_[option] = option_type; default_parameters_[option] = default_parameter; } void ArgumentParser::parse(int argc, char **argv) { assert(argc % 2 == 1); for (int i = 1; i < argc; i += 2) { for (auto &[option, _] : option_types_) { std::string argv_option = std::string(argv[i]); assert(argv_option.substr(0, 2) == "--"); if (option == argv_option.substr(2)) { assert(not custom_parameters_.count(option)); std::string argv_parameter = std::string(argv[i + 1]); custom_parameters_[option] = argv_parameter; } } } } std::set ArgumentParser::options() { std::set