8
8
*/
9
9
10
10
#include " xenia/cpu/backend/a64/a64_sequences.h"
11
+ #include " xenia/cpu/backend/a64/a64_util.h"
11
12
12
13
#include < algorithm>
13
14
#include < cstring>
@@ -1026,12 +1027,7 @@ EMITTER_OPCODE_TABLE(OPCODE_EXTRACT, EXTRACT_I8, EXTRACT_I16, EXTRACT_I32);
1026
1027
struct SPLAT_I8 : Sequence<SPLAT_I8, I<OPCODE_SPLAT, V128Op, I8Op>> {
1027
1028
static void Emit (A64Emitter& e, const EmitArgType& i) {
1028
1029
if (i.src1 .is_constant ) {
1029
- if (i.src1 .constant () <= 0xFF ) {
1030
- e.MOVI (i.dest .reg ().B16 (), i.src1 .constant ());
1031
- return ;
1032
- }
1033
- e.MOV (W0, i.src1 .constant ());
1034
- e.DUP (i.dest .reg ().B16 (), W0);
1030
+ e.MOVI (i.dest .reg ().B16 (), i.src1 .constant ());
1035
1031
} else {
1036
1032
e.DUP (i.dest .reg ().B16 (), i.src1 );
1037
1033
}
@@ -1040,9 +1036,12 @@ struct SPLAT_I8 : Sequence<SPLAT_I8, I<OPCODE_SPLAT, V128Op, I8Op>> {
1040
1036
struct SPLAT_I16 : Sequence<SPLAT_I16, I<OPCODE_SPLAT, V128Op, I16Op>> {
1041
1037
static void Emit (A64Emitter& e, const EmitArgType& i) {
1042
1038
if (i.src1 .is_constant ) {
1043
- if (i.src1 .constant () <= 0xFF ) {
1039
+ if (( i.src1 .constant () & 0xFF'00 ) == 0 ) {
1044
1040
e.MOVI (i.dest .reg ().H8 (), i.src1 .constant ());
1045
1041
return ;
1042
+ } else if ((i.src1 .constant () & 0x00'FF ) == 0 ) {
1043
+ e.MOVI (i.dest .reg ().H8 (), i.src1 .constant (), oaknut::util::LSL, 8 );
1044
+ return ;
1046
1045
}
1047
1046
e.MOV (W0, i.src1 .constant ());
1048
1047
e.DUP (i.dest .reg ().H8 (), W0);
@@ -1054,9 +1053,22 @@ struct SPLAT_I16 : Sequence<SPLAT_I16, I<OPCODE_SPLAT, V128Op, I16Op>> {
1054
1053
struct SPLAT_I32 : Sequence<SPLAT_I32, I<OPCODE_SPLAT, V128Op, I32Op>> {
1055
1054
static void Emit (A64Emitter& e, const EmitArgType& i) {
1056
1055
if (i.src1 .is_constant ) {
1057
- if (i.src1 .constant () <= 0xFF ) {
1056
+ oaknut::FImm8 fp8 (0 );
1057
+ if (f32_to_fimm8 (i.src1 .value ->constant .u32 , fp8)) {
1058
+ e.FMOV (i.dest .reg ().S4 (), fp8);
1059
+ return ;
1060
+ } else if ((i.src1 .constant () & 0xFF'FF'FF'00 ) == 0 ) {
1058
1061
e.MOVI (i.dest .reg ().S4 (), i.src1 .constant ());
1059
1062
return ;
1063
+ } else if ((i.src1 .constant () & 0xFF'FF'00'FF ) == 0 ) {
1064
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .constant (), oaknut::util::LSL, 8 );
1065
+ return ;
1066
+ } else if ((i.src1 .constant () & 0xFF'00'FF'FF ) == 0 ) {
1067
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .constant (), oaknut::util::LSL, 16 );
1068
+ return ;
1069
+ } else if ((i.src1 .constant () & 0x00'FF'FF'FF ) == 0 ) {
1070
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .constant (), oaknut::util::LSL, 24 );
1071
+ return ;
1060
1072
}
1061
1073
e.MOV (W0, i.src1 .constant ());
1062
1074
e.DUP (i.dest .reg ().S4 (), W0);
@@ -1068,8 +1080,24 @@ struct SPLAT_I32 : Sequence<SPLAT_I32, I<OPCODE_SPLAT, V128Op, I32Op>> {
1068
1080
struct SPLAT_F32 : Sequence<SPLAT_F32, I<OPCODE_SPLAT, V128Op, F32Op>> {
1069
1081
static void Emit (A64Emitter& e, const EmitArgType& i) {
1070
1082
if (i.src1 .is_constant ) {
1071
- if (i.src1 .value ->constant .i32 <= 0xFF ) {
1072
- e.MOVI (i.dest .reg ().S4 (), i.src1 .value ->constant .i32 );
1083
+ oaknut::FImm8 fp8 (0 );
1084
+ if (f32_to_fimm8 (i.src1 .value ->constant .u32 , fp8)) {
1085
+ e.FMOV (i.dest .reg ().S4 (), fp8);
1086
+ return ;
1087
+ } else if ((i.src1 .value ->constant .u32 & 0xFF'FF'FF'00 ) == 0 ) {
1088
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .value ->constant .u32 );
1089
+ return ;
1090
+ } else if ((i.src1 .value ->constant .u32 & 0xFF'FF'00'FF ) == 0 ) {
1091
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .value ->constant .u32 , oaknut::util::LSL,
1092
+ 8 );
1093
+ return ;
1094
+ } else if ((i.src1 .value ->constant .u32 & 0xFF'00'FF'FF ) == 0 ) {
1095
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .value ->constant .u32 , oaknut::util::LSL,
1096
+ 16 );
1097
+ return ;
1098
+ } else if ((i.src1 .value ->constant .u32 & 0x00'FF'FF'FF ) == 0 ) {
1099
+ e.MOVI (i.dest .reg ().S4 (), i.src1 .value ->constant .u32 , oaknut::util::LSL,
1100
+ 24 );
1073
1101
return ;
1074
1102
}
1075
1103
e.MOV (W0, i.src1 .value ->constant .i32 );
0 commit comments