diff options
author | Mike Pall <mike> | 2011-03-30 21:56:05 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-03-30 21:56:05 +0200 |
commit | 5b06b298a2ddd95b0512c483d78589a84faad4e6 (patch) | |
tree | 28cce064a8f7addd329f6e7aec7975d1b77c7634 /src | |
parent | a0e47110556130957f261ede57383d3a3eb73d52 (diff) | |
download | luajit-5b06b298a2ddd95b0512c483d78589a84faad4e6.tar.gz luajit-5b06b298a2ddd95b0512c483d78589a84faad4e6.tar.bz2 luajit-5b06b298a2ddd95b0512c483d78589a84faad4e6.zip |
ARM: Add binary arithmetic instructions.
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: |