diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_arm.dasc | 170 |
1 files changed, 155 insertions, 15 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index cec04893..0cefc471 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -92,6 +92,7 @@ | |||
| 92 | |.macro decode_RB8, dst, ins; and dst, MASKR8, ins, lsr #21; .endmacro | 92 | |.macro decode_RB8, dst, ins; and dst, MASKR8, ins, lsr #21; .endmacro |
| 93 | |.macro decode_RC8, dst, ins; and dst, MASKR8, ins, lsr #13; .endmacro | 93 | |.macro decode_RC8, dst, ins; and dst, MASKR8, ins, lsr #13; .endmacro |
| 94 | |.macro decode_RD, dst, ins; lsr dst, ins, #16; .endmacro | 94 | |.macro decode_RD, dst, ins; lsr dst, ins, #16; .endmacro |
| 95 | |.macro decode_OP, dst, ins; and dst, ins, #255; .endmacro | ||
| 95 | | | 96 | | |
| 96 | |// Instruction fetch. | 97 | |// Instruction fetch. |
| 97 | |.macro ins_NEXT1 | 98 | |.macro ins_NEXT1 |
| @@ -189,6 +190,10 @@ | |||
| 189 | | | 190 | | |
| 190 | |//----------------------------------------------------------------------- | 191 | |//----------------------------------------------------------------------- |
| 191 | 192 | ||
| 193 | #if !LJ_DUALNUM | ||
| 194 | #error "Only dual-number mode supported for ARM target" | ||
| 195 | #endif | ||
| 196 | |||
| 192 | /* Generate subroutines used by opcodes and other parts of the VM. */ | 197 | /* Generate subroutines used by opcodes and other parts of the VM. */ |
| 193 | /* The .code_sub section should be last to help static branch prediction. */ | 198 | /* The .code_sub section should be last to help static branch prediction. */ |
| 194 | static void build_subroutines(BuildCtx *ctx) | 199 | static void build_subroutines(BuildCtx *ctx) |
| @@ -417,7 +422,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 417 | | NYI | 422 | | NYI |
| 418 | | | 423 | | |
| 419 | |->cont_nop: | 424 | |->cont_nop: |
| 420 | | NYI | 425 | | ins_next |
| 421 | | | 426 | | |
| 422 | |->cont_ra: // RA = resultptr | 427 | |->cont_ra: // RA = resultptr |
| 423 | | NYI | 428 | | NYI |
| @@ -434,18 +439,44 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 434 | |//-- Arithmetic metamethods --------------------------------------------- | 439 | |//-- Arithmetic metamethods --------------------------------------------- |
| 435 | | | 440 | | |
| 436 | |->vmeta_arith_vn: | 441 | |->vmeta_arith_vn: |
| 437 | | NYI | 442 | | decode_RB8 RB, INS |
| 443 | | decode_RC8 RC, INS | ||
| 444 | | add CARG3, BASE, RB | ||
| 445 | | add CARG4, KBASE, RC | ||
| 446 | | b >1 | ||
| 438 | | | 447 | | |
| 439 | |->vmeta_arith_nv: | 448 | |->vmeta_arith_nv: |
| 440 | | NYI | 449 | | decode_RB8 RB, INS |
| 450 | | decode_RC8 RC, INS | ||
| 451 | | add CARG4, BASE, RB | ||
| 452 | | add CARG3, KBASE, RC | ||
| 453 | | b >1 | ||
| 441 | | | 454 | | |
| 442 | |->vmeta_unm: | 455 | |->vmeta_unm: |
| 443 | | NYI | 456 | | add CARG3, BASE, RC |
| 457 | | add CARG4, BASE, RC | ||
| 458 | | b >1 | ||
| 444 | | | 459 | | |
| 445 | |->vmeta_arith_vv: | 460 | |->vmeta_arith_vv: |
| 446 | | NYI | 461 | | decode_RB8 RB, INS |
| 447 | | | 462 | | decode_RC8 RC, INS |
| 463 | | add CARG3, BASE, RB | ||
| 464 | | add CARG4, BASE, RC | ||
| 465 | |1: | ||
| 466 | | decode_OP OP, INS | ||
| 467 | | add CARG2, BASE, RA | ||
| 468 | | str BASE, L->base | ||
| 469 | | mov CARG1, L | ||
| 470 | | str PC, SAVE_PC | ||
| 471 | | str OP, ARG5 | ||
| 472 | | bl extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op) | ||
| 473 | | // Returns NULL (finished) or TValue * (metamethod). | ||
| 474 | | cmp CRET1, #0 | ||
| 475 | | beq ->cont_nop | ||
| 476 | | | ||
| 477 | | // Call metamethod for binary op. | ||
| 448 | |->vmeta_binop: | 478 | |->vmeta_binop: |
| 479 | | // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2 | ||
| 449 | | NYI | 480 | | NYI |
| 450 | | | 481 | | |
| 451 | |->vmeta_len: | 482 | |->vmeta_len: |
| @@ -790,6 +821,9 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 790 | |->vm_trunc: | 821 | |->vm_trunc: |
| 791 | #endif | 822 | #endif |
| 792 | | | 823 | | |
| 824 | |->vm_mod: | ||
| 825 | | NYI | ||
| 826 | | | ||
| 793 | |->vm_powi: | 827 | |->vm_powi: |
| 794 | #if LJ_HASJIT | 828 | #if LJ_HASJIT |
| 795 | | NYI | 829 | | NYI |
| @@ -804,7 +838,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 804 | |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -) | 838 | |// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -) |
| 805 | |// and basic math functions. ORDER ARITH | 839 | |// and basic math functions. ORDER ARITH |
| 806 | |->vm_foldarith: | 840 | |->vm_foldarith: |
| 807 | | NYI | 841 | | ldr OP, [sp] |
| 842 | | cmp OP, #1 | ||
| 843 | | blo extern __aeabi_dadd | ||
| 844 | | beq extern __aeabi_dsub | ||
| 845 | | cmp OP, #3 | ||
| 846 | | blo extern __aeabi_dmul | ||
| 847 | | beq extern __aeabi_ddiv | ||
| 848 | | cmp OP, #5 | ||
| 849 | | blo ->vm_mod | ||
| 850 | | beq extern pow | ||
| 851 | | cmp OP, #7 | ||
| 852 | | eorlo CARG2, CARG2, #0x80000000 | ||
| 853 | | biceq CARG2, CARG2, #0x80000000 | ||
| 854 | | bxls lr | ||
| 855 | | NYI // Other operations only needed by JIT compiler. | ||
| 808 | | | 856 | | |
| 809 | |//----------------------------------------------------------------------- | 857 | |//----------------------------------------------------------------------- |
| 810 | |//-- Miscellaneous functions -------------------------------------------- | 858 | |//-- Miscellaneous functions -------------------------------------------- |
| @@ -925,33 +973,125 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 925 | | ins_next3 | 973 | | ins_next3 |
| 926 | |2: | 974 | |2: |
| 927 | | checktab CARG2, ->vmeta_len | 975 | | checktab CARG2, ->vmeta_len |
| 928 | | blx extern lj_tab_len // (GCtab *t) | 976 | | bl extern lj_tab_len // (GCtab *t) |
| 929 | | // Returns uint32_t (but less than 2^31). | 977 | | // Returns uint32_t (but less than 2^31). |
| 930 | | b <1 | 978 | | b <1 |
| 931 | break; | 979 | break; |
| 932 | 980 | ||
| 933 | /* -- Binary ops -------------------------------------------------------- */ | 981 | /* -- Binary ops -------------------------------------------------------- */ |
| 934 | 982 | ||
| 983 | |.macro ins_arithcheck, cond, ncond, target | ||
| 984 | ||if (vk == 1) { | ||
| 985 | | cmn CARG4, #-LJ_TISNUM | ||
| 986 | | cmn..cond CARG2, #-LJ_TISNUM | ||
| 987 | ||} else { | ||
| 988 | | cmn CARG2, #-LJ_TISNUM | ||
| 989 | | cmn..cond CARG4, #-LJ_TISNUM | ||
| 990 | ||} | ||
| 991 | | b..ncond target | ||
| 992 | |.endmacro | ||
| 993 | |.macro ins_arithcheck_int, target | ||
| 994 | | ins_arithcheck eq, ne, target | ||
| 995 | |.endmacro | ||
| 996 | |.macro ins_arithcheck_num, target | ||
| 997 | | ins_arithcheck lo, hs, target | ||
| 998 | |.endmacro | ||
| 999 | | | ||
| 1000 | |.macro ins_arithpre | ||
| 1001 | | decode_RB8 RB, INS | ||
| 1002 | | decode_RC8 RC, INS | ||
| 1003 | | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8 | ||
| 1004 | ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); | ||
| 1005 | ||switch (vk) { | ||
| 1006 | ||case 0: | ||
| 1007 | | ldrd CARG12, [BASE, RB] | ||
| 1008 | | ldrd CARG34, [KBASE, RC] | ||
| 1009 | || break; | ||
| 1010 | ||case 1: | ||
| 1011 | | ldrd CARG34, [BASE, RB] | ||
| 1012 | | ldrd CARG12, [KBASE, RC] | ||
| 1013 | || break; | ||
| 1014 | ||default: | ||
| 1015 | | ldrd CARG12, [BASE, RB] | ||
| 1016 | | ldrd CARG34, [BASE, RC] | ||
| 1017 | || break; | ||
| 1018 | ||} | ||
| 1019 | |.endmacro | ||
| 1020 | | | ||
| 1021 | |.macro ins_arithfallback, ins | ||
| 1022 | ||switch (vk) { | ||
| 1023 | ||case 0: | ||
| 1024 | | ins ->vmeta_arith_vn | ||
| 1025 | || break; | ||
| 1026 | ||case 1: | ||
| 1027 | | ins ->vmeta_arith_nv | ||
| 1028 | || break; | ||
| 1029 | ||default: | ||
| 1030 | | ins ->vmeta_arith_vv | ||
| 1031 | || break; | ||
| 1032 | ||} | ||
| 1033 | |.endmacro | ||
| 1034 | | | ||
| 1035 | |.macro ins_arithdn, intins, fpcall | ||
| 1036 | | ins_arithpre | ||
| 1037 | | ins_next1 | ||
| 1038 | | ins_arithcheck_int >5 | ||
| 1039 | |.if "intins" == "smull" | ||
| 1040 | | smull CARG1, RC, CARG3, CARG1 | ||
| 1041 | | cmp RC, CARG1, asr #31 | ||
| 1042 | | ins_arithfallback bne | ||
| 1043 | |.else | ||
| 1044 | | intins CARG1, CARG1, CARG3 | ||
| 1045 | | ins_arithfallback bvs | ||
| 1046 | |.endif | ||
| 1047 | |4: | ||
| 1048 | | ins_next2 | ||
| 1049 | | strd CARG12, [BASE, RA] | ||
| 1050 | | ins_next3 | ||
| 1051 | |5: // FP variant. | ||
| 1052 | | ins_arithfallback ins_arithcheck_num | ||
| 1053 | | bl fpcall | ||
| 1054 | | ins_next1 | ||
| 1055 | | b <4 | ||
| 1056 | |.endmacro | ||
| 1057 | | | ||
| 1058 | |.macro ins_arithfp, fpcall | ||
| 1059 | | ins_arithpre | ||
| 1060 | ||if (op == BC_MODVN) { | ||
| 1061 | | ->BC_MODVN_Z: | ||
| 1062 | ||} | ||
| 1063 | | ins_arithfallback ins_arithcheck_num | ||
| 1064 | | bl fpcall | ||
| 1065 | | ins_next1 | ||
| 1066 | | ins_next2 | ||
| 1067 | | strd CARG12, [BASE, RA] | ||
| 1068 | | ins_next3 | ||
| 1069 | |.endmacro | ||
| 1070 | |||
| 935 | case BC_ADDVN: case BC_ADDNV: case BC_ADDVV: | 1071 | case BC_ADDVN: case BC_ADDNV: case BC_ADDVV: |
| 936 | | NYI | 1072 | | ins_arithdn adds, extern __aeabi_dadd |
| 937 | break; | 1073 | break; |
| 938 | case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: | 1074 | case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: |
| 939 | | NYI | 1075 | | ins_arithdn subs, extern __aeabi_dsub |
| 940 | break; | 1076 | break; |
| 941 | case BC_MULVN: case BC_MULNV: case BC_MULVV: | 1077 | case BC_MULVN: case BC_MULNV: case BC_MULVV: |
| 942 | | NYI | 1078 | | ins_arithdn smull, extern __aeabi_dmul |
| 943 | break; | 1079 | break; |
| 944 | case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: | 1080 | case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: |
| 945 | | NYI | 1081 | | ins_arithfp extern __aeabi_ddiv |
| 946 | break; | 1082 | break; |
| 947 | case BC_MODVN: | 1083 | case BC_MODVN: |
| 948 | | NYI | 1084 | | // NYI: integer arithmetic. |
| 1085 | | // Note: __aeabi_idivmod is unsuitable. It uses trunc, not floor. | ||
| 1086 | | ins_arithfp ->vm_mod | ||
| 949 | break; | 1087 | break; |
| 950 | case BC_MODNV: case BC_MODVV: | 1088 | case BC_MODNV: case BC_MODVV: |
| 951 | | NYI | 1089 | | ins_arithpre |
| 1090 | | b ->BC_MODVN_Z | ||
| 952 | break; | 1091 | break; |
| 953 | case BC_POW: | 1092 | case BC_POW: |
| 954 | | NYI | 1093 | | // NYI: (partial) integer arithmetic. |
| 1094 | | ins_arithfp extern pow | ||
| 955 | break; | 1095 | break; |
| 956 | 1096 | ||
| 957 | case BC_CAT: | 1097 | case BC_CAT: |
