aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-30 21:56:05 +0200
committerMike Pall <mike>2011-03-30 21:56:05 +0200
commit5b06b298a2ddd95b0512c483d78589a84faad4e6 (patch)
tree28cce064a8f7addd329f6e7aec7975d1b77c7634 /src
parenta0e47110556130957f261ede57383d3a3eb73d52 (diff)
downloadluajit-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.dasc170
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. */
194static void build_subroutines(BuildCtx *ctx) 199static 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: