88 */
99
1010#include " xenia/cpu/backend/a64/a64_sequences.h"
11+ #include " xenia/cpu/backend/a64/a64_util.h"
1112
1213#include < algorithm>
1314#include < cstring>
@@ -1026,12 +1027,7 @@ EMITTER_OPCODE_TABLE(OPCODE_EXTRACT, EXTRACT_I8, EXTRACT_I16, EXTRACT_I32);
10261027struct SPLAT_I8 : Sequence<SPLAT_I8, I<OPCODE_SPLAT, V128Op, I8Op>> {
10271028 static void Emit (A64Emitter& e, const EmitArgType& i) {
10281029 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 ());
10351031 } else {
10361032 e.DUP (i.dest .reg ().B16 (), i.src1 );
10371033 }
@@ -1040,9 +1036,12 @@ struct SPLAT_I8 : Sequence<SPLAT_I8, I<OPCODE_SPLAT, V128Op, I8Op>> {
10401036struct SPLAT_I16 : Sequence<SPLAT_I16, I<OPCODE_SPLAT, V128Op, I16Op>> {
10411037 static void Emit (A64Emitter& e, const EmitArgType& i) {
10421038 if (i.src1 .is_constant ) {
1043- if (i.src1 .constant () <= 0xFF ) {
1039+ if (( i.src1 .constant () & 0xFF'00 ) == 0 ) {
10441040 e.MOVI (i.dest .reg ().H8 (), i.src1 .constant ());
10451041 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 ;
10461045 }
10471046 e.MOV (W0, i.src1 .constant ());
10481047 e.DUP (i.dest .reg ().H8 (), W0);
@@ -1054,9 +1053,22 @@ struct SPLAT_I16 : Sequence<SPLAT_I16, I<OPCODE_SPLAT, V128Op, I16Op>> {
10541053struct SPLAT_I32 : Sequence<SPLAT_I32, I<OPCODE_SPLAT, V128Op, I32Op>> {
10551054 static void Emit (A64Emitter& e, const EmitArgType& i) {
10561055 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 ) {
10581061 e.MOVI (i.dest .reg ().S4 (), i.src1 .constant ());
10591062 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 ;
10601072 }
10611073 e.MOV (W0, i.src1 .constant ());
10621074 e.DUP (i.dest .reg ().S4 (), W0);
@@ -1068,8 +1080,24 @@ struct SPLAT_I32 : Sequence<SPLAT_I32, I<OPCODE_SPLAT, V128Op, I32Op>> {
10681080struct SPLAT_F32 : Sequence<SPLAT_F32, I<OPCODE_SPLAT, V128Op, F32Op>> {
10691081 static void Emit (A64Emitter& e, const EmitArgType& i) {
10701082 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 );
10731101 return ;
10741102 }
10751103 e.MOV (W0, i.src1 .value ->constant .i32 );
0 commit comments