aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-01 20:27:39 +0200
committerMike Pall <mike>2010-09-01 20:27:39 +0200
commit7457ee869aa182fbecec6c7f567d93fd85382b57 (patch)
tree3f37e9c07dd50fe851ad7657ac2152b75ad65979 /src
parent222e01fa83c758f5322b17b53294ca67aa2bda68 (diff)
downloadluajit-7457ee869aa182fbecec6c7f567d93fd85382b57.tar.gz
luajit-7457ee869aa182fbecec6c7f567d93fd85382b57.tar.bz2
luajit-7457ee869aa182fbecec6c7f567d93fd85382b57.zip
PPC: Add comparison instructions.
Diffstat (limited to 'src')
-rw-r--r--src/buildvm_ppc.dasc133
1 files changed, 128 insertions, 5 deletions
diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc
index 6ac1b036..abd688e9 100644
--- a/src/buildvm_ppc.dasc
+++ b/src/buildvm_ppc.dasc
@@ -922,23 +922,146 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
922 /* Remember: all ops branch for a true comparison, fall through otherwise. */ 922 /* Remember: all ops branch for a true comparison, fall through otherwise. */
923 923
924 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: 924 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
925 | NYI 925 | // RA = src1*8, RD = src2*8, JMP with RD = target
926 | evlddx TMP0, BASE, RA
927 | addi PC, PC, 4
928 | evlddx TMP1, BASE, RD
929 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
930 | lwz INS, -4(PC)
931 | evmergehi RB, TMP0, TMP1
932 | decode_RD4 TMP2, INS
933 | checknum RB
934 | add TMP2, TMP2, TMP3
935 | checkanyfail ->vmeta_comp
936 if (op == BC_ISLT || op == BC_ISGE) {
937 | efdcmplt TMP0, TMP1
938 } else {
939 | efdcmpgt TMP0, TMP1
940 }
941 if (op == BC_ISLT || op == BC_ISGT) {
942 | iselgt PC, TMP2, PC
943 } else {
944 | iselgt PC, PC, TMP2
945 }
946 | ins_next
926 break; 947 break;
927 948
928 case BC_ISEQV: case BC_ISNEV: 949 case BC_ISEQV: case BC_ISNEV:
929 | NYI 950 vk = op == BC_ISEQV;
951 | // RA = src1*8, RD = src2*8, JMP with RD = target
952 | evlddx TMP0, BASE, RA
953 | addi PC, PC, 4
954 | evlddx TMP1, BASE, RD
955 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
956 | lwz INS, -4(PC)
957 | evmergehi RB, TMP0, TMP1
958 | decode_RD4 TMP2, INS
959 | checknum RB
960 | add TMP2, TMP2, TMP3
961 | checkanyfail >5
962 | efdcmpeq TMP0, TMP1
963 if (vk) {
964 | iselgt PC, TMP2, PC
965 } else {
966 | iselgt PC, PC, TMP2
967 }
968 |1:
969 | ins_next
970 |
971 |5: // Either or both types are not numbers.
972 | evcmpeq TMP0, TMP1
973 | not TMP3, RB
974 | cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive?
975 | crorc 4*cr7+lt, 4*cr0+so, 4*cr0+lt // 1: Same tv or different type.
976 | cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata?
977 | crandc 4*cr7+gt, 4*cr0+lt, 4*cr1+gt // 2: Same type and primitive.
978 | mr SAVE0, PC
979 if (vk) {
980 | isel PC, TMP2, PC, 4*cr7+gt
981 } else {
982 | isel TMP2, PC, TMP2, 4*cr7+gt
983 }
984 | cror 4*cr7+lt, 4*cr7+lt, 4*cr7+gt // 1 or 2.
985 if (vk) {
986 | isel PC, TMP2, PC, 4*cr0+so
987 } else {
988 | isel PC, PC, TMP2, 4*cr0+so
989 }
990 | blt cr7, <1 // Done if 1 or 2.
991 | blt cr6, <1 // Done if not tab/ud.
992 |
993 | // Different tables or userdatas. Need to check __eq metamethod.
994 | // Field metatable must be at same offset for GCtab and GCudata!
995 | lwz TAB:TMP3, TAB:TMP1->metatable
996 | li RB, 1-vk // ne = 0 or 1.
997 | cmplwi TAB:TMP3, 0
998 | beq <1 // No metatable?
999 | lbz TMP0, TAB:TMP3->nomm
1000 | andi. TMP0, TMP0, 1<<MM_eq
1001 | bne <1 // Or 'no __eq' flag set?
1002 | mr PC, SAVE0 // Restore old PC.
1003 | b ->vmeta_equal // Handle __eq metamethod.
930 break; 1004 break;
931 1005
932 case BC_ISEQS: case BC_ISNES: 1006 case BC_ISEQS: case BC_ISNES:
933 | NYI 1007 vk = op == BC_ISEQS;
1008 | // RA = src*8, RD = str_const*8 (~), JMP with RD = target
1009 | evlddx TMP0, BASE, RA
1010 | srwi RD, RD, 1
1011 | lwz INS, 0(PC)
1012 | subfic RD, RD, -4
1013 | addi PC, PC, 4
1014 | lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
1015 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
1016 | decode_RD4 TMP2, INS
1017 | evmergelo STR:TMP1, TISSTR, STR:TMP1
1018 | add TMP2, TMP2, TMP3
1019 | evcmpeq TMP0, STR:TMP1
1020 if (vk) {
1021 | isel PC, TMP2, PC, 4*cr0+so
1022 } else {
1023 | isel PC, PC, TMP2, 4*cr0+so
1024 }
1025 | ins_next
934 break; 1026 break;
935 1027
936 case BC_ISEQN: case BC_ISNEN: 1028 case BC_ISEQN: case BC_ISNEN:
937 | NYI 1029 vk = op == BC_ISEQN;
1030 | // RA = src*8, RD = num_const*8, JMP with RD = target
1031 | evlddx TMP0, BASE, RA
1032 | addi PC, PC, 4
1033 | evlddx TMP1, KBASE, RD
1034 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
1035 | lwz INS, -4(PC)
1036 | efdcmpeq TMP0, TMP1 // NYI: avoid comparison with NaN.
1037 | decode_RD4 TMP2, INS
1038 | add TMP2, TMP2, TMP3
1039 if (vk) {
1040 | iselgt PC, TMP2, PC
1041 } else {
1042 | iselgt PC, PC, TMP2
1043 }
1044 | ins_next
938 break; 1045 break;
939 1046
940 case BC_ISEQP: case BC_ISNEP: 1047 case BC_ISEQP: case BC_ISNEP:
941 | NYI 1048 vk = op == BC_ISEQP;
1049 | // RA = src*8, RD = primitive_type*8 (~), JMP with RD = target
1050 | lwzx TMP0, BASE, RA
1051 | srwi TMP1, RD, 3
1052 | lwz INS, 0(PC)
1053 | addi PC, PC, 4
1054 | not TMP1, TMP1
1055 | addis TMP3, PC, -(BCBIAS_J*4 >> 16)
1056 | cmplw TMP0, TMP1
1057 | decode_RD4 TMP2, INS
1058 | add TMP2, TMP2, TMP3
1059 if (vk) {
1060 | iseleq PC, TMP2, PC
1061 } else {
1062 | iseleq PC, PC, TMP2
1063 }
1064 | ins_next
942 break; 1065 break;
943 1066
944 /* -- Unary test and copy ops ------------------------------------------- */ 1067 /* -- Unary test and copy ops ------------------------------------------- */