Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,997 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include "src/codegen/code-factory.h"
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "src/utils/ostreams.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using DisasmIa320Test = TestWithIsolate;
#define __ assm.
TEST_F(DisasmIa320Test, DisasmIa320) {
HandleScope handle_scope(isolate());
uint8_t buffer[8192];
Assembler assm(AssemblerOptions{},
ExternalAssemblerBuffer(buffer, sizeof buffer));
// Short immediate instructions
__ adc(eax, 12345678);
__ add(eax, Immediate(12345678));
__ or_(eax, 12345678);
__ sub(eax, Immediate(12345678));
__ xor_(eax, 12345678);
__ and_(eax, 12345678);
Handle<FixedArray> foo =
isolate()->factory()->NewFixedArray(10, AllocationType::kOld);
__ cmp(eax, foo);
// ---- This one caused crash
__ mov(ebx, Operand(esp, ecx, times_2, 0)); // [esp+ecx*4]
// ---- All instructions that I can think of
__ add(edx, ebx);
__ add(edx, Operand(12, RelocInfo::NO_INFO));
__ add(edx, Operand(ebx, 0));
__ add(edx, Operand(ebx, 16));
__ add(edx, Operand(ebx, 1999));
__ add(edx, Operand(ebx, -4));
__ add(edx, Operand(ebx, -1999));
__ add(edx, Operand(esp, 0));
__ add(edx, Operand(esp, 16));
__ add(edx, Operand(esp, 1999));
__ add(edx, Operand(esp, -4));
__ add(edx, Operand(esp, -1999));
__ nop();
__ add(esi, Operand(ecx, times_4, 0));
__ add(esi, Operand(ecx, times_4, 24));
__ add(esi, Operand(ecx, times_4, -4));
__ add(esi, Operand(ecx, times_4, -1999));
__ nop();
__ add(edi, Operand(ebp, ecx, times_4, 0));
__ add(edi, Operand(ebp, ecx, times_4, 12));
__ add(edi, Operand(ebp, ecx, times_4, -8));
__ add(edi, Operand(ebp, ecx, times_4, -3999));
__ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
__ bswap(eax);
__ nop();
__ add(ebx, Immediate(12));
__ nop();
__ adc(edx, Operand(ebx));
__ adc(ecx, 12);
__ adc(ecx, 1000);
__ nop();
__ and_(edx, 3);
__ and_(edx, Operand(esp, 4));
__ cmp(edx, 3);
__ cmp(edx, Operand(esp, 4));
__ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
Handle<FixedArray> foo2 =
isolate()->factory()->NewFixedArray(10, AllocationType::kOld);
__ cmp(ebx, foo2);
__ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
__ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
__ or_(edx, 3);
__ xor_(edx, 3);
__ nop();
__ cpuid();
__ movsx_b(edx, ecx);
__ movsx_w(edx, ecx);
__ movzx_b(edx, ecx);
__ movzx_w(edx, ecx);
__ nop();
__ imul(edx, ecx);
__ shld(edx, ecx, 10);
__ shld_cl(edx, ecx);
__ shrd(edx, ecx, 10);
__ shrd_cl(edx, ecx);
__ bts(edx, ecx);
__ bts(Operand(ebx, ecx, times_4, 0), ecx);
__ nop();
__ pushad();
__ popad();
__ pushfd();
__ popfd();
__ push(Immediate(12));
__ push(Immediate(23456));
__ push(ecx);
__ push(esi);
__ push(Operand(ebp, StandardFrameConstants::kFunctionOffset));
__ push(Operand(ebx, ecx, times_4, 0));
__ push(Operand(ebx, ecx, times_4, 0));
__ push(Operand(ebx, ecx, times_4, 10000));
__ pop(edx);
__ pop(eax);
__ pop(Operand(ebx, ecx, times_4, 0));
__ nop();
__ add(edx, Operand(esp, 16));
__ add(edx, ecx);
__ mov_b(edx, ecx);
__ mov_b(ecx, 6);
__ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
__ mov_b(Operand(esp, 16), edx);
__ mov_w(edx, Operand(esp, 16));
__ mov_w(Operand(esp, 16), edx);
__ nop();
__ movsx_w(edx, Operand(esp, 12));
__ movsx_b(edx, Operand(esp, 12));
__ movzx_w(edx, Operand(esp, 12));
__ movzx_b(edx, Operand(esp, 12));
__ nop();
__ mov(edx, 1234567);
__ mov(edx, Operand(esp, 12));
__ mov(Operand(ebx, ecx, times_4, 10000), Immediate(12345));
__ mov(Operand(ebx, ecx, times_4, 10000), edx);
__ nop();
__ dec_b(edx);
__ dec_b(Operand(eax, 10));
__ dec_b(Operand(ebx, ecx, times_4, 10000));
__ dec(edx);
__ cdq();
__ nop();
__ idiv(edx);
__ idiv(Operand(edx, ecx, times_1, 1));
__ idiv(Operand(esp, 12));
__ div(edx);
__ div(Operand(edx, ecx, times_1, 1));
__ div(Operand(esp, 12));
__ mul(edx);
__ neg(edx);
__ not_(edx);
__ test(Operand(ebx, ecx, times_4, 10000), Immediate(123456));
__ imul(edx, Operand(ebx, ecx, times_4, 10000));
__ imul(edx, ecx, 12);
__ imul(edx, Operand(edx, eax, times_2, 42), 8);
__ imul(edx, ecx, 1000);
__ imul(edx, Operand(ebx, ecx, times_4, 1), 9000);
__ inc(edx);
__ inc(Operand(ebx, ecx, times_4, 10000));
__ push(Operand(ebx, ecx, times_4, 10000));
__ pop(Operand(ebx, ecx, times_4, 10000));
__ call(Operand(ebx, ecx, times_4, 10000));
__ jmp(Operand(ebx, ecx, times_4, 10000));
__ lea(edx, Operand(ebx, ecx, times_4, 10000));
__ or_(edx, 12345);
__ or_(edx, Operand(ebx, ecx, times_4, 10000));
__ nop();
__ rcl(edx, 1);
__ rcl(edx, 7);
__ rcr(edx, 1);
__ rcr(edx, 7);
__ ror(edx, 1);
__ ror(edx, 6);
__ ror_cl(edx);
__ ror(Operand(ebx, ecx, times_4, 10000), 1);
__ ror(Operand(ebx, ecx, times_4, 10000), 6);
__ ror_cl(Operand(ebx, ecx, times_4, 10000));
__ sar(edx, 1);
__ sar(edx, 6);
__ sar_cl(edx);
__ sar(Operand(ebx, ecx, times_4, 10000), 1);
__ sar(Operand(ebx, ecx, times_4, 10000), 6);
__ sar_cl(Operand(ebx, ecx, times_4, 10000));
__ sbb(edx, Operand(ebx, ecx, times_4, 10000));
__ shl(edx, 1);
__ shl(edx, 6);
__ shl_cl(edx);
__ shl(Operand(ebx, ecx, times_4, 10000), 1);
__ shl(Operand(ebx, ecx, times_4, 10000), 6);
__ shl_cl(Operand(ebx, ecx, times_4, 10000));
__ shrd_cl(Operand(ebx, ecx, times_4, 10000), edx);
__ shr(edx, 1);
__ shr(edx, 7);
__ shr_cl(edx);
__ shr(Operand(ebx, ecx, times_4, 10000), 1);
__ shr(Operand(ebx, ecx, times_4, 10000), 6);
__ shr_cl(Operand(ebx, ecx, times_4, 10000));
// Immediates
__ adc(edx, 12345);
__ add(ebx, Immediate(12));
__ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
__ and_(ebx, 12345);
__ cmp(ebx, 12345);
__ cmp(ebx, Immediate(12));
__ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
__ cmpb(eax, Immediate(100));
__ or_(ebx, 12345);
__ sub(ebx, Immediate(12));
__ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
__ xor_(ebx, 12345);
__ imul(edx, ecx, 12);
__ imul(edx, ecx, 1000);
__ cld();
__ rep_movs();
__ rep_stos();
__ stos();
__ sub(edx, Operand(ebx, ecx, times_4, 10000));
__ sub(edx, ebx);
__ test(edx, Immediate(12345));
__ test(edx, Operand(ebx, ecx, times_8, 10000));
__ test(Operand(esi, edi, times_1, -20000000), Immediate(300000000));
__ test_b(edx, Operand(ecx, ebx, times_2, 1000));
__ test_b(Operand(eax, -20), Immediate(0x9A));
__ nop();
__ xor_(edx, 12345);
__ xor_(edx, Operand(ebx, ecx, times_8, 10000));
__ bts(Operand(ebx, ecx, times_8, 10000), edx);
__ hlt();
__ int3();
__ ret(0);
__ ret(8);
// Calls
Label L1, L2;
__ bind(&L1);
__ nop();
__ call(&L1);
__ call(&L2);
__ nop();
__ bind(&L2);
__ call(Operand(ebx, ecx, times_4, 10000));
__ nop();
__ jmp(&L1);
__ jmp(Operand(ebx, ecx, times_4, 10000));
__ nop();
Label Ljcc;
__ nop();
// long jumps
__ j(overflow, &Ljcc);
__ j(no_overflow, &Ljcc);
__ j(below, &Ljcc);
__ j(above_equal, &Ljcc);
__ j(equal, &Ljcc);
__ j(not_equal, &Ljcc);
__ j(below_equal, &Ljcc);
__ j(above, &Ljcc);
__ j(sign, &Ljcc);
__ j(not_sign, &Ljcc);
__ j(parity_even, &Ljcc);
__ j(parity_odd, &Ljcc);
__ j(less, &Ljcc);
__ j(greater_equal, &Ljcc);
__ j(less_equal, &Ljcc);
__ j(greater, &Ljcc);
__ nop();
__ bind(&Ljcc);
// short jumps
__ j(overflow, &Ljcc);
__ j(no_overflow, &Ljcc);
__ j(below, &Ljcc);
__ j(above_equal, &Ljcc);
__ j(equal, &Ljcc);
__ j(not_equal, &Ljcc);
__ j(below_equal, &Ljcc);
__ j(above, &Ljcc);
__ j(sign, &Ljcc);
__ j(not_sign, &Ljcc);
__ j(parity_even, &Ljcc);
__ j(parity_odd, &Ljcc);
__ j(less, &Ljcc);
__ j(greater_equal, &Ljcc);
__ j(less_equal, &Ljcc);
__ j(greater, &Ljcc);
// 0xD9 instructions
__ nop();
__ fld(1);
__ fld1();
__ fldz();
__ fldpi();
__ fabs();
__ fchs();
__ fprem();
__ fprem1();
__ fincstp();
__ ftst();
__ fxch(3);
__ fld_s(Operand(ebx, ecx, times_4, 10000));
__ fstp_s(Operand(ebx, ecx, times_4, 10000));
__ ffree(3);
__ fld_d(Operand(ebx, ecx, times_4, 10000));
__ fstp_d(Operand(ebx, ecx, times_4, 10000));
__ nop();
__ fild_s(Operand(ebx, ecx, times_4, 10000));
__ fistp_s(Operand(ebx, ecx, times_4, 10000));
__ fild_d(Operand(ebx, ecx, times_4, 10000));
__ fistp_d(Operand(ebx, ecx, times_4, 10000));
__ fnstsw_ax();
__ nop();
__ fadd(3);
__ fsub(3);
__ fmul(3);
__ fdiv(3);
__ faddp(3);
__ fsubp(3);
__ fmulp(3);
__ fdivp(3);
__ fcompp();
__ fwait();
__ frndint();
__ fninit();
__ nop();
// SSE instruction
{
// Move operation
__ movaps(xmm0, xmm1);
__ movups(xmm0, xmm1);
__ movups(xmm0, Operand(edx, 4));
__ movups(Operand(edx, 4), xmm0);
__ shufps(xmm0, xmm0, 0x0);
__ cvtsd2ss(xmm0, xmm1);
__ cvtsd2ss(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movq(xmm0, Operand(edx, 4));
__ movhlps(xmm0, xmm1);
__ movlps(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movlps(Operand(ebx, ecx, times_4, 10000), xmm0);
__ movhps(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movhps(Operand(ebx, ecx, times_4, 10000), xmm0);
__ unpcklps(xmm0, xmm1);
// logic operation
__ andps(xmm0, xmm1);
__ andps(xmm0, Operand(ebx, ecx, times_4, 10000));
__ andnps(xmm0, xmm1);
__ andnps(xmm0, Operand(ebx, ecx, times_4, 10000));
__ orps(xmm0, xmm1);
__ orps(xmm0, Operand(ebx, ecx, times_4, 10000));
__ xorps(xmm0, xmm1);
__ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
// Arithmetic operation
__ addss(xmm1, xmm0);
__ addss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ mulss(xmm1, xmm0);
__ mulss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ subss(xmm1, xmm0);
__ subss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ divss(xmm1, xmm0);
__ divss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ maxss(xmm1, xmm0);
__ maxss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ minss(xmm1, xmm0);
__ minss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ sqrtss(xmm1, xmm0);
__ sqrtss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ addps(xmm1, xmm0);
__ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ subps(xmm1, xmm0);
__ subps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ mulps(xmm1, xmm0);
__ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ divps(xmm1, xmm0);
__ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ minps(xmm1, xmm0);
__ minps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ maxps(xmm1, xmm0);
__ maxps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ rcpps(xmm1, xmm0);
__ rcpps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ sqrtps(xmm1, xmm0);
__ sqrtps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ rsqrtps(xmm1, xmm0);
__ rsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cmpeqps(xmm5, xmm1);
__ cmpeqps(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpltps(xmm5, xmm1);
__ cmpltps(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpleps(xmm5, xmm1);
__ cmpleps(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpunordps(xmm5, xmm1);
__ cmpunordps(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpneqps(xmm5, xmm1);
__ cmpneqps(xmm5, Operand(ebx, ecx, times_4, 10000));
__ ucomiss(xmm0, xmm1);
__ ucomiss(xmm0, Operand(ebx, ecx, times_4, 10000));
}
{
__ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
__ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cvtss2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cvtss2sd(xmm1, xmm0);
__ cvtdq2ps(xmm1, xmm0);
__ cvtdq2ps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cvtdq2pd(xmm1, xmm0);
__ cvtps2pd(xmm1, xmm0);
__ cvtpd2ps(xmm1, xmm0);
__ cvttps2dq(xmm1, xmm0);
__ cvttps2dq(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cvttpd2dq(xmm1, xmm0);
__ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
// 128 bit move instructions.
__ movdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movdqa(Operand(ebx, ecx, times_4, 10000), xmm0);
__ movdqa(xmm1, xmm0);
__ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
__ movdqu(xmm1, xmm0);
__ movapd(xmm0, xmm1);
__ movapd(xmm0, Operand(edx, 4));
__ movupd(xmm0, Operand(edx, 4));
__ movd(xmm0, edi);
__ movd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ movd(eax, xmm1);
__ movd(Operand(ebx, ecx, times_4, 10000), xmm1);
__ ucomisd(xmm0, xmm1);
__ cmpltsd(xmm0, xmm1);
__ andpd(xmm0, xmm1);
__ andpd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ andnpd(xmm0, xmm1);
__ andnpd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ orpd(xmm0, xmm1);
__ orpd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ xorpd(xmm0, xmm1);
__ xorpd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ addpd(xmm1, xmm0);
__ addpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ subpd(xmm1, xmm0);
__ subpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ mulpd(xmm1, xmm0);
__ mulpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ divpd(xmm1, xmm0);
__ divpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ minpd(xmm1, xmm0);
__ minpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ maxpd(xmm1, xmm0);
__ maxpd(xmm1, Operand(ebx, ecx, times_4, 10000));
__ cmpeqpd(xmm5, xmm1);
__ cmpeqpd(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpltpd(xmm5, xmm1);
__ cmpltpd(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmplepd(xmm5, xmm1);
__ cmplepd(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpunordpd(xmm5, xmm1);
__ cmpunordpd(xmm5, Operand(ebx, ecx, times_4, 10000));
__ cmpneqpd(xmm5, xmm1);
__ cmpneqpd(xmm5, Operand(ebx, ecx, times_4, 10000));
__ psllw(xmm0, 17);
__ pslld(xmm0, 17);
__ psrlw(xmm0, 17);
__ psrld(xmm0, 17);
__ psraw(xmm0, 17);
__ psrad(xmm0, 17);
__ psllq(xmm0, 17);
__ psrlq(xmm0, 17);
__ pshufhw(xmm5, xmm1, 5);
__ pshufhw(xmm5, Operand(edx, 4), 5);
__ pshuflw(xmm5, xmm1, 5);
__ pshuflw(xmm5, Operand(edx, 4), 5);
__ pshufd(xmm5, xmm1, 5);
__ pshufd(xmm5, Operand(edx, 4), 5);
__ pinsrw(xmm5, edx, 5);
__ pinsrw(xmm5, Operand(edx, 4), 5);
__ movmskpd(edx, xmm5);
__ movmskps(edx, xmm5);
__ pmovmskb(edx, xmm5);
#define EMIT_SSE2_INSTR(instruction, notUsed1, notUsed2, notUsed3) \
__ instruction(xmm5, xmm1); \
__ instruction(xmm5, Operand(edx, 4));
SSE2_INSTRUCTION_LIST(EMIT_SSE2_INSTR)
SSE2_INSTRUCTION_LIST_SD(EMIT_SSE2_INSTR)
#undef EMIT_SSE2_INSTR
}
// cmov.
{
__ cmov(overflow, eax, Operand(eax, 0));
__ cmov(no_overflow, eax, Operand(eax, 1));
__ cmov(below, eax, Operand(eax, 2));
__ cmov(above_equal, eax, Operand(eax, 3));
__ cmov(equal, eax, Operand(ebx, 0));
__ cmov(not_equal, eax, Operand(ebx, 1));
__ cmov(below_equal, eax, Operand(ebx, 2));
__ cmov(above, eax, Operand(ebx, 3));
__ cmov(sign, eax, Operand(ecx, 0));
__ cmov(not_sign, eax, Operand(ecx, 1));
__ cmov(parity_even, eax, Operand(ecx, 2));
__ cmov(parity_odd, eax, Operand(ecx, 3));
__ cmov(less, eax, Operand(edx, 0));
__ cmov(greater_equal, eax, Operand(edx, 1));
__ cmov(less_equal, eax, Operand(edx, 2));
__ cmov(greater, eax, Operand(edx, 3));
}
{
if (CpuFeatures::IsSupported(SSE3)) {
CpuFeatureScope scope(&assm, SSE3);
__ haddps(xmm1, xmm0);
__ haddps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ movddup(xmm1, Operand(eax, 5));
__ movddup(xmm1, xmm2);
__ movshdup(xmm1, xmm2);
}
}
#define EMIT_SSE34_INSTR(instruction, notUsed1, notUsed2, notUsed3, notUsed4) \
__ instruction(xmm5, xmm1); \
__ instruction(xmm5, Operand(edx, 4));
{
if (CpuFeatures::IsSupported(SSSE3)) {
CpuFeatureScope scope(&assm, SSSE3);
SSSE3_INSTRUCTION_LIST(EMIT_SSE34_INSTR)
SSSE3_UNOP_INSTRUCTION_LIST(EMIT_SSE34_INSTR)
__ palignr(xmm5, xmm1, 5);
__ palignr(xmm5, Operand(edx, 4), 5);
}
}
{
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatureScope scope(&assm, SSE4_1);
__ pblendw(xmm5, xmm1, 5);
__ pblendw(xmm5, Operand(edx, 4), 5);
__ pextrb(eax, xmm0, 1);
__ pextrb(Operand(edx, 4), xmm0, 1);
__ pextrw(eax, xmm0, 1);
__ pextrw(Operand(edx, 4), xmm0, 1);
__ pextrd(eax, xmm0, 1);
__ pextrd(Operand(edx, 4), xmm0, 1);
__ insertps(xmm1, xmm2, 0);
__ insertps(xmm1, Operand(edx, 4), 0);
__ pinsrb(xmm1, eax, 0);
__ pinsrb(xmm1, Operand(edx, 4), 0);
__ pinsrd(xmm1, eax, 0);
__ pinsrd(xmm1, Operand(edx, 4), 0);
__ extractps(eax, xmm1, 0);
__ blendvps(xmm3, xmm1);
__ blendvpd(xmm3, xmm1);
__ pblendvb(xmm3, xmm1);
SSE4_INSTRUCTION_LIST(EMIT_SSE34_INSTR)
SSE4_RM_INSTRUCTION_LIST(EMIT_SSE34_INSTR)
}
}
#undef EMIT_SSE34_INSTR
{
if (CpuFeatures::IsSupported(SSE4_2)) {
CpuFeatureScope scope(&assm, SSE4_2);
__ pcmpgtq(xmm0, xmm1);
}
}
// AVX instruction
{
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope scope(&assm, AVX);
__ vaddss(xmm0, xmm1, xmm2);
__ vaddss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmulss(xmm0, xmm1, xmm2);
__ vmulss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vsubss(xmm0, xmm1, xmm2);
__ vsubss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vdivss(xmm0, xmm1, xmm2);
__ vdivss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vminss(xmm0, xmm1, xmm2);
__ vminss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmaxss(xmm0, xmm1, xmm2);
__ vmaxss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vsqrtss(xmm0, xmm1, xmm2);
__ vsqrtss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vucomisd(xmm0, xmm1);
__ vucomisd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vucomiss(xmm0, xmm1);
__ vucomiss(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vandps(xmm0, xmm1, xmm2);
__ vandps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vandnps(xmm0, xmm1, xmm2);
__ vandnps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vorps(xmm0, xmm1, xmm2);
__ vorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vxorps(xmm0, xmm1, xmm2);
__ vxorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vaddps(xmm0, xmm1, xmm2);
__ vaddps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmulps(xmm0, xmm1, xmm2);
__ vmulps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vsubps(xmm0, xmm1, xmm2);
__ vsubps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vminps(xmm0, xmm1, xmm2);
__ vminps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vdivps(xmm0, xmm1, xmm2);
__ vdivps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmaxps(xmm0, xmm1, xmm2);
__ vmaxps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vrcpps(xmm1, xmm0);
__ vrcpps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vsqrtps(xmm1, xmm0);
__ vsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vrsqrtps(xmm1, xmm0);
__ vrsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovups(xmm0, xmm1);
__ vmovups(xmm0, Operand(edx, 4));
__ vmovaps(xmm0, xmm1);
__ vmovapd(xmm0, xmm1);
__ vmovapd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vmovupd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vshufps(xmm0, xmm1, xmm2, 3);
__ vshufps(xmm0, xmm1, Operand(edx, 4), 3);
__ vhaddps(xmm0, xmm1, xmm2);
__ vhaddps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovhlps(xmm0, xmm1, xmm2);
__ vmovlps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovlps(Operand(ebx, ecx, times_4, 10000), xmm0);
__ vmovhps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovhps(Operand(ebx, ecx, times_4, 10000), xmm0);
__ vcmpeqps(xmm5, xmm4, xmm1);
__ vcmpeqps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpltps(xmm5, xmm4, xmm1);
__ vcmpltps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpleps(xmm5, xmm4, xmm1);
__ vcmpleps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpunordps(xmm5, xmm4, xmm1);
__ vcmpunordps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpneqps(xmm5, xmm4, xmm1);
__ vcmpneqps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpgeps(xmm5, xmm4, xmm1);
__ vcmpgeps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vandpd(xmm0, xmm1, xmm2);
__ vandpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vandnpd(xmm0, xmm1, xmm2);
__ vandnpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vorpd(xmm0, xmm1, xmm2);
__ vorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vxorpd(xmm0, xmm1, xmm2);
__ vxorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vaddpd(xmm0, xmm1, xmm2);
__ vaddpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmulpd(xmm0, xmm1, xmm2);
__ vmulpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vsubpd(xmm0, xmm1, xmm2);
__ vsubpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vminpd(xmm0, xmm1, xmm2);
__ vminpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vdivpd(xmm0, xmm1, xmm2);
__ vdivpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmaxpd(xmm0, xmm1, xmm2);
__ vmaxpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
__ vcmpeqpd(xmm5, xmm4, xmm1);
__ vcmpeqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpltpd(xmm5, xmm4, xmm1);
__ vcmpltpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmplepd(xmm5, xmm4, xmm1);
__ vcmplepd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpunordpd(xmm5, xmm4, xmm1);
__ vcmpunordpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vcmpneqpd(xmm5, xmm4, xmm1);
__ vcmpneqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000));
__ vpsllw(xmm0, xmm7, 21);
__ vpslld(xmm0, xmm7, 21);
__ vpsllq(xmm0, xmm7, 21);
__ vpsrlw(xmm0, xmm7, 21);
__ vpsrld(xmm0, xmm7, 21);
__ vpsrlq(xmm0, xmm7, 21);
__ vpsraw(xmm0, xmm7, 21);
__ vpsrad(xmm0, xmm7, 21);
__ vpshufhw(xmm5, xmm1, 5);
__ vpshufhw(xmm5, Operand(edx, 4), 5);
__ vpshuflw(xmm5, xmm1, 5);
__ vpshuflw(xmm5, Operand(edx, 4), 5);
__ vpshufd(xmm5, xmm1, 5);
__ vpshufd(xmm5, Operand(edx, 4), 5);
__ vpblendw(xmm5, xmm1, xmm0, 5);
__ vpblendw(xmm5, xmm1, Operand(edx, 4), 5);
__ vpalignr(xmm5, xmm1, xmm0, 5);
__ vpalignr(xmm5, xmm1, Operand(edx, 4), 5);
__ vpextrb(eax, xmm0, 1);
__ vpextrb(Operand(edx, 4), xmm0, 1);
__ vpextrw(eax, xmm0, 1);
__ vpextrw(Operand(edx, 4), xmm0, 1);
__ vpextrd(eax, xmm0, 1);
__ vpextrd(Operand(edx, 4), xmm0, 1);
__ vinsertps(xmm0, xmm1, xmm2, 0);
__ vinsertps(xmm0, xmm1, Operand(edx, 4), 0);
__ vpinsrb(xmm0, xmm1, eax, 0);
__ vpinsrb(xmm0, xmm1, Operand(edx, 4), 0);
__ vpinsrw(xmm0, xmm1, eax, 0);
__ vpinsrw(xmm0, xmm1, Operand(edx, 4), 0);
__ vpinsrd(xmm0, xmm1, eax, 0);
__ vpinsrd(xmm0, xmm1, Operand(edx, 4), 0);
__ vblendvps(xmm3, xmm1, xmm4, xmm6);
__ vblendvpd(xmm3, xmm1, xmm4, xmm6);
__ vpblendvb(xmm3, xmm1, xmm4, xmm6);
__ vcvtdq2ps(xmm1, xmm0);
__ vcvtdq2ps(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vcvtdq2pd(xmm1, xmm0);
__ vcvtps2pd(xmm1, xmm0);
__ vcvtpd2ps(xmm1, xmm0);
__ vcvttps2dq(xmm1, xmm0);
__ vcvttps2dq(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vcvttpd2dq(xmm1, xmm0);
__ vcvtsd2ss(xmm2, xmm3, Operand(ebx, ecx, times_4, 10000));
__ vcvtsd2ss(xmm2, xmm3, xmm6);
__ vcvtss2sd(xmm2, xmm3, Operand(ebx, ecx, times_1, 10000));
__ vcvtss2sd(xmm2, xmm3, xmm6);
__ vcvttsd2si(eax, Operand(ebx, ecx, times_4, 10000));
__ vcvttsd2si(ebx, xmm6);
__ vcvttss2si(eax, Operand(ebx, ecx, times_4, 10000));
__ vcvttss2si(ebx, xmm6);
__ vmovddup(xmm1, xmm2);
__ vmovddup(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovshdup(xmm1, xmm2);
__ vbroadcastss(xmm1, Operand(ebx, ecx, times_4, 10000));
__ vmovdqa(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vmovdqa(xmm0, xmm7);
__ vmovdqu(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vmovdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
__ vmovd(xmm0, edi);
__ vmovd(xmm0, Operand(ebx, ecx, times_4, 10000));
__ vmovd(eax, xmm1);
__ vmovd(Operand(ebx, ecx, times_4, 10000), xmm1);
__ vmovmskpd(edx, xmm5);
__ vmovmskps(edx, xmm5);
__ vpmovmskb(ebx, xmm1);
__ vpcmpgtq(xmm0, xmm1, xmm2);
__ vroundsd(xmm0, xmm3, xmm2, kRoundDown);
__ vroundss(xmm0, xmm3, xmm2, kRoundDown);
#define EMIT_SSE2_AVXINSTR(instruction, notUsed1, notUsed2, notUsed3) \
__ v##instruction(xmm7, xmm5, xmm1); \
__ v##instruction(xmm7, xmm5, Operand(edx, 4));
SSE2_INSTRUCTION_LIST(EMIT_SSE2_AVXINSTR)
SSE2_INSTRUCTION_LIST_SD(EMIT_SSE2_AVXINSTR)
#undef EMIT_SSE2_AVXINSTR
#define EMIT_SSE34_AVXINSTR(instruction, notUsed1, notUsed2, notUsed3, \
notUsed4) \
__ v##instruction(xmm7, xmm5, xmm1); \
__ v##instruction(xmm7, xmm5, Operand(edx, 4));
SSSE3_INSTRUCTION_LIST(EMIT_SSE34_AVXINSTR)
SSE4_INSTRUCTION_LIST(EMIT_SSE34_AVXINSTR)
#undef EMIT_SSE34_AVXINSTR
#define EMIT_SSE4_RM_AVXINSTR(instruction, notUsed1, notUsed2, notUsed3, \
notUsed4) \
__ v##instruction(xmm5, xmm1); \
__ v##instruction(xmm5, Operand(edx, 4));
SSSE3_UNOP_INSTRUCTION_LIST(EMIT_SSE4_RM_AVXINSTR)
SSE4_RM_INSTRUCTION_LIST(EMIT_SSE4_RM_AVXINSTR)
#undef EMIT_SSE4_RM_AVXINSTR
}
}
// AVX2 instructions.
{
if (CpuFeatures::IsSupported(AVX2)) {
CpuFeatureScope scope(&assm, AVX2);
#define EMIT_AVX2_BROADCAST(instruction, notUsed1, notUsed2, notUsed3, \
notUsed4) \
__ instruction(xmm0, xmm1); \
__ instruction(xmm0, Operand(ebx, ecx, times_4, 10000));
AVX2_BROADCAST_LIST(EMIT_AVX2_BROADCAST)
}
}
// FMA3 instruction
{
if (CpuFeatures::IsSupported(FMA3)) {
CpuFeatureScope scope(&assm, FMA3);
#define EMIT_FMA(instr, notUsed1, notUsed2, notUsed3, notUsed4, notUsed5, \
notUsed6) \
__ instr(xmm2, xmm1, xmm0); \
__ instr(xmm2, xmm1, Operand(ebx, ecx, times_4, 10000));
FMA_INSTRUCTION_LIST(EMIT_FMA)
#undef EMIT_FMA
}
}
// BMI1 instructions
{
if (CpuFeatures::IsSupported(BMI1)) {
CpuFeatureScope scope(&assm, BMI1);
__ andn(eax, ebx, ecx);
__ andn(eax, ebx, Operand(ebx, ecx, times_4, 10000));
__ bextr(eax, ebx, ecx);
__ bextr(eax, Operand(ebx, ecx, times_4, 10000), ebx);
__ blsi(eax, ebx);
__ blsi(eax, Operand(ebx, ecx, times_4, 10000));
__ blsmsk(eax, ebx);
__ blsmsk(eax, Operand(ebx, ecx, times_4, 10000));
__ blsr(eax, ebx);
__ blsr(eax, Operand(ebx, ecx, times_4, 10000));
__ tzcnt(eax, ebx);
__ tzcnt(eax, Operand(ebx, ecx, times_4, 10000));
}
}
// LZCNT instructions
{
if (CpuFeatures::IsSupported(LZCNT)) {
CpuFeatureScope scope(&assm, LZCNT);
__ lzcnt(eax, ebx);
__ lzcnt(eax, Operand(ebx, ecx, times_4, 10000));
}
}
// POPCNT instructions
{
if (CpuFeatures::IsSupported(POPCNT)) {
CpuFeatureScope scope(&assm, POPCNT);
__ popcnt(eax, ebx);
__ popcnt(eax, Operand(ebx, ecx, times_4, 10000));
}
}
// BMI2 instructions
{
if (CpuFeatures::IsSupported(BMI2)) {
CpuFeatureScope scope(&assm, BMI2);
__ bzhi(eax, ebx, ecx);
__ bzhi(eax, Operand(ebx, ecx, times_4, 10000), ebx);
__ mulx(eax, ebx, ecx);
__ mulx(eax, ebx, Operand(ebx, ecx, times_4, 10000));
__ pdep(eax, ebx, ecx);
__ pdep(eax, ebx, Operand(ebx, ecx, times_4, 10000));
__ pext(eax, ebx, ecx);
__ pext(eax, ebx, Operand(ebx, ecx, times_4, 10000));
__ sarx(eax, ebx, ecx);
__ sarx(eax, Operand(ebx, ecx, times_4, 10000), ebx);
__ shlx(eax, ebx, ecx);
__ shlx(eax, Operand(ebx, ecx, times_4, 10000), ebx);
__ shrx(eax, ebx, ecx);
__ shrx(eax, Operand(ebx, ecx, times_4, 10000), ebx);
__ rorx(eax, ebx, 31);
__ rorx(eax, Operand(ebx, ecx, times_4, 10000), 31);
}
}
// xadd.
{
__ xadd(Operand(eax, 8), eax);
__ xadd_w(Operand(ebx, 8), eax);
__ xadd_b(Operand(ebx, 8), eax);
}
// xchg.
{
__ xchg_b(eax, Operand(eax, 8));
__ xchg_w(eax, Operand(ebx, 8));
__ xchg(eax, eax);
__ xchg(eax, ebx);
__ xchg(ebx, ebx);
__ xchg(ebx, Operand(esp, 12));
}
// cmpxchg.
{
__ cmpxchg_b(Operand(esp, 12), eax);
__ cmpxchg_w(Operand(ebx, ecx, times_4, 10000), eax);
__ cmpxchg(Operand(ebx, ecx, times_4, 10000), eax);
__ cmpxchg(Operand(ebx, ecx, times_4, 10000), eax);
__ cmpxchg8b(Operand(ebx, ecx, times_8, 10000));
}
// lock prefix.
{
__ lock();
__ cmpxchg(Operand(esp, 12), ebx);
__ lock();
__ xchg_w(eax, Operand(ecx, 8));
}
// Nop instructions
for (int i = 0; i < 16; i++) {
__ Nop(i);
}
__ mfence();
__ lfence();
__ pause();
__ ret(0);
CodeDesc desc;
assm.GetCode(isolate(), &desc);
Handle<Code> code =
Factory::CodeBuilder(isolate(), desc, CodeKind::FOR_TESTING).Build();
USE(code);
#ifdef OBJECT_PRINT
StdoutStream os;
Print(*code, os);
Address begin = code->instruction_start();
Address end = code->instruction_end();
disasm::Disassembler::Disassemble(stdout, reinterpret_cast<uint8_t*>(begin),
reinterpret_cast<uint8_t*>(end));
#endif
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,958 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <stdio.h>
#include <stdlib.h>
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using DisasmLoong64Test = TestWithIsolate;
bool DisassembleAndCompare(uint8_t* pc, const char* compare_string) {
disasm::NameConverter converter;
disasm::Disassembler disasm(converter);
base::EmbeddedVector<char, 128> disasm_buffer;
/* if (prev_instr_compact_branch) {
disasm.InstructionDecode(disasm_buffer, pc);
pc += 4;
}*/
disasm.InstructionDecode(disasm_buffer, pc);
if (strcmp(compare_string, disasm_buffer.begin()) != 0) {
fprintf(stderr,
"expected: \n"
"%s\n"
"disassembled: \n"
"%s\n\n",
compare_string, disasm_buffer.begin());
return false;
}
return true;
}
// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
#define SET_UP() \
HandleScope scope(isolate()); \
uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(4 * 1024)); \
Assembler assm(AssemblerOptions{}, \
ExternalAssemblerBuffer(buffer, 4 * 1024)); \
bool failure = false;
// This macro assembles one instruction using the preallocated assembler and
// disassembles the generated instruction, comparing the output to the expected
// value. If the comparison fails an error message is printed, but the test
// continues to run until the end.
#define COMPARE(asm_, compare_string) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
}
// Verify that all invocations of the COMPARE macro passed successfully.
// Exit with a failure if at least one of the tests failed.
#define VERIFY_RUN() \
if (failure) { \
FATAL("LOONG64 Disassembler tests failed.\n"); \
}
#define COMPARE_PC_REL(asm_, compare_string, offset) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
char str_with_address[100]; \
printf("%p\n", static_cast<void*>(progcounter)); \
snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
compare_string, static_cast<void*>(progcounter + (offset * 4))); \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
}
TEST_F(DisasmLoong64Test, TypeOp6) {
SET_UP();
COMPARE(jirl(ra, t7, 0), "4c000261 jirl ra, t7, 0x0");
COMPARE(jirl(ra, t7, 32767), "4dfffe61 jirl ra, t7, 0x1fffc");
COMPARE(jirl(ra, t7, -32768), "4e000261 jirl ra, t7, 0x20000");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp6PC) {
SET_UP();
COMPARE_PC_REL(beqz(t7, 1048575), "43fffe6f beqz t7, 0x3ffffc",
1048575);
COMPARE_PC_REL(beqz(t0, -1048576), "40000190 beqz t0, 0x400000",
-1048576);
COMPARE_PC_REL(beqz(t1, 0), "400001a0 beqz t1, 0x0", 0);
COMPARE_PC_REL(bnez(a2, 1048575), "47fffccf bnez a2, 0x3ffffc",
1048575);
COMPARE_PC_REL(bnez(s3, -1048576), "44000350 bnez s3, 0x400000",
-1048576);
COMPARE_PC_REL(bnez(t8, 0), "44000280 bnez t8, 0x0", 0);
COMPARE_PC_REL(bceqz(FCC0, 1048575),
"4bfffc0f bceqz fcc0, 0x3ffffc", 1048575);
COMPARE_PC_REL(bceqz(FCC0, -1048576),
"48000010 bceqz fcc0, 0x400000", -1048576);
COMPARE_PC_REL(bceqz(FCC0, 0), "48000000 bceqz fcc0, 0x0", 0);
COMPARE_PC_REL(bcnez(FCC0, 1048575),
"4bfffd0f bcnez fcc0, 0x3ffffc", 1048575);
COMPARE_PC_REL(bcnez(FCC0, -1048576),
"48000110 bcnez fcc0, 0x400000", -1048576);
COMPARE_PC_REL(bcnez(FCC0, 0), "48000100 bcnez fcc0, 0x0", 0);
COMPARE_PC_REL(b(33554431), "53fffdff b 0x7fffffc",
33554431);
COMPARE_PC_REL(b(-33554432), "50000200 b 0x8000000",
-33554432);
COMPARE_PC_REL(b(0), "50000000 b 0x0", 0);
COMPARE_PC_REL(beq(t0, a6, 32767),
"59fffd8a beq t0, a6, 0x1fffc", 32767);
COMPARE_PC_REL(beq(t1, a0, -32768),
"5a0001a4 beq t1, a0, 0x20000", -32768);
COMPARE_PC_REL(beq(a4, t1, 0), "5800010d beq a4, t1, 0x0", 0);
COMPARE_PC_REL(bne(a3, a4, 32767),
"5dfffce8 bne a3, a4, 0x1fffc", 32767);
COMPARE_PC_REL(bne(a6, a5, -32768),
"5e000149 bne a6, a5, 0x20000", -32768);
COMPARE_PC_REL(bne(a4, a5, 0), "5c000109 bne a4, a5, 0x0", 0);
COMPARE_PC_REL(blt(a4, a6, 32767),
"61fffd0a blt a4, a6, 0x1fffc", 32767);
COMPARE_PC_REL(blt(a4, a5, -32768),
"62000109 blt a4, a5, 0x20000", -32768);
COMPARE_PC_REL(blt(a4, a6, 0), "6000010a blt a4, a6, 0x0", 0);
COMPARE_PC_REL(bge(s7, a5, 32767),
"65ffffc9 bge s7, a5, 0x1fffc", 32767);
COMPARE_PC_REL(bge(a1, a3, -32768),
"660000a7 bge a1, a3, 0x20000", -32768);
COMPARE_PC_REL(bge(a5, s3, 0), "6400013a bge a5, s3, 0x0", 0);
COMPARE_PC_REL(bltu(a5, s7, 32767),
"69fffd3e bltu a5, s7, 0x1fffc", 32767);
COMPARE_PC_REL(bltu(a4, a5, -32768),
"6a000109 bltu a4, a5, 0x20000", -32768);
COMPARE_PC_REL(bltu(a4, t6, 0), "68000112 bltu a4, t6, 0x0", 0);
COMPARE_PC_REL(bgeu(a7, a6, 32767),
"6dfffd6a bgeu a7, a6, 0x1fffc", 32767);
COMPARE_PC_REL(bgeu(a5, a3, -32768),
"6e000127 bgeu a5, a3, 0x20000", -32768);
COMPARE_PC_REL(bgeu(t2, t1, 0), "6c0001cd bgeu t2, t1, 0x0", 0);
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp7) {
SET_UP();
COMPARE(lu12i_w(a4, 524287), "14ffffe8 lu12i.w a4, 0x7ffff");
COMPARE(lu12i_w(a5, -524288), "15000009 lu12i.w a5, 0x80000");
COMPARE(lu12i_w(a6, 0), "1400000a lu12i.w a6, 0x0");
COMPARE(lu32i_d(a7, 524287), "16ffffeb lu32i.d a7, 0x7ffff");
COMPARE(lu32i_d(t0, -524288), "1700000c lu32i.d t0, 0x80000");
COMPARE(lu32i_d(t1, 0), "1600000d lu32i.d t1, 0x0");
COMPARE(pcaddi(t1, 1), "1800002d pcaddi t1, 0x1");
COMPARE(pcaddi(t2, 524287), "18ffffee pcaddi t2, 0x7ffff");
COMPARE(pcaddi(t3, -524288), "1900000f pcaddi t3, 0x80000");
COMPARE(pcaddi(t4, 0), "18000010 pcaddi t4, 0x0");
COMPARE(pcalau12i(t5, 524287), "1afffff1 pcalau12i t5, 0x7ffff");
COMPARE(pcalau12i(t6, -524288), "1b000012 pcalau12i t6, 0x80000");
COMPARE(pcalau12i(a4, 0), "1a000008 pcalau12i a4, 0x0");
COMPARE(pcaddu12i(a5, 524287), "1cffffe9 pcaddu12i a5, 0x7ffff");
COMPARE(pcaddu12i(a6, -524288), "1d00000a pcaddu12i a6, 0x80000");
COMPARE(pcaddu12i(a7, 0), "1c00000b pcaddu12i a7, 0x0");
COMPARE(pcaddu18i(t0, 524287), "1effffec pcaddu18i t0, 0x7ffff");
COMPARE(pcaddu18i(t1, -524288), "1f00000d pcaddu18i t1, 0x80000");
COMPARE(pcaddu18i(t2, 0), "1e00000e pcaddu18i t2, 0x0");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp8) {
SET_UP();
COMPARE(ll_w(t2, t3, 32764),
"207ffdee ll.w t2, t3, 32764(0x7ffc)");
COMPARE(ll_w(t3, t4, -32768),
"2080020f ll.w t3, t4, -32768(0x8000)");
COMPARE(ll_w(t5, t6, 0), "20000251 ll.w t5, t6, 0(0x0)");
COMPARE(sc_w(a6, a7, 32764),
"217ffd6a sc.w a6, a7, 32764(0x7ffc)");
COMPARE(sc_w(t0, t1, -32768),
"218001ac sc.w t0, t1, -32768(0x8000)");
COMPARE(sc_w(t2, t3, 0), "210001ee sc.w t2, t3, 0(0x0)");
COMPARE(ll_d(a0, a1, 32764),
"227ffca4 ll.d a0, a1, 32764(0x7ffc)");
COMPARE(ll_d(a2, a3, -32768),
"228000e6 ll.d a2, a3, -32768(0x8000)");
COMPARE(ll_d(a4, a5, 0), "22000128 ll.d a4, a5, 0(0x0)");
COMPARE(sc_d(t4, t5, 32764),
"237ffe30 sc.d t4, t5, 32764(0x7ffc)");
COMPARE(sc_d(t6, a0, -32768),
"23800092 sc.d t6, a0, -32768(0x8000)");
COMPARE(sc_d(a1, a2, 0), "230000c5 sc.d a1, a2, 0(0x0)");
COMPARE(ldptr_w(a4, a5, 32764),
"247ffd28 ldptr.w a4, a5, 32764(0x7ffc)");
COMPARE(ldptr_w(a6, a7, -32768),
"2480016a ldptr.w a6, a7, -32768(0x8000)");
COMPARE(ldptr_w(t0, t1, 0), "240001ac ldptr.w t0, t1, 0(0x0)");
COMPARE(stptr_w(a4, a5, 32764),
"257ffd28 stptr.w a4, a5, 32764(0x7ffc)");
COMPARE(stptr_w(a6, a7, -32768),
"2580016a stptr.w a6, a7, -32768(0x8000)");
COMPARE(stptr_w(t0, t1, 0), "250001ac stptr.w t0, t1, 0(0x0)");
COMPARE(ldptr_d(t2, t3, 32764),
"267ffdee ldptr.d t2, t3, 32764(0x7ffc)");
COMPARE(ldptr_d(t4, t5, -32768),
"26800230 ldptr.d t4, t5, -32768(0x8000)");
COMPARE(ldptr_d(t6, a4, 0), "26000112 ldptr.d t6, a4, 0(0x0)");
COMPARE(stptr_d(a5, a6, 32764),
"277ffd49 stptr.d a5, a6, 32764(0x7ffc)");
COMPARE(stptr_d(a7, t0, -32768),
"2780018b stptr.d a7, t0, -32768(0x8000)");
COMPARE(stptr_d(t1, t2, 0), "270001cd stptr.d t1, t2, 0(0x0)");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp10) {
SET_UP();
COMPARE(bstrins_w(a4, a5, 31, 16),
"007f4128 bstrins.w a4, a5, 31, 16");
COMPARE(bstrins_w(a6, a7, 5, 0), "0065016a bstrins.w a6, a7, 5, 0");
COMPARE(bstrins_d(a3, zero_reg, 17, 0),
"00910007 bstrins.d a3, zero_reg, 17, 0");
COMPARE(bstrins_d(t1, zero_reg, 17, 0),
"0091000d bstrins.d t1, zero_reg, 17, 0");
COMPARE(bstrpick_w(t0, t1, 31, 29),
"007ff5ac bstrpick.w t0, t1, 31, 29");
COMPARE(bstrpick_w(a4, a5, 16, 0),
"00708128 bstrpick.w a4, a5, 16, 0");
COMPARE(bstrpick_d(a5, a5, 31, 0),
"00df0129 bstrpick.d a5, a5, 31, 0");
COMPARE(bstrpick_d(a4, a4, 25, 2),
"00d90908 bstrpick.d a4, a4, 25, 2");
COMPARE(slti(t2, a5, 2047),
"021ffd2e slti t2, a5, 2047(0x7ff)");
COMPARE(slti(a7, a1, -2048),
"022000ab slti a7, a1, -2048(0x800)");
COMPARE(sltui(a7, a7, 2047),
"025ffd6b sltui a7, a7, 2047(0x7ff)");
COMPARE(sltui(t1, t1, -2048),
"026001ad sltui t1, t1, -2048(0x800)");
COMPARE(addi_w(t0, t2, 2047),
"029ffdcc addi.w t0, t2, 2047(0x7ff)");
COMPARE(addi_w(a0, a0, -2048),
"02a00084 addi.w a0, a0, -2048(0x800)");
COMPARE(addi_d(a0, zero_reg, 2047),
"02dffc04 addi.d a0, zero_reg, 2047(0x7ff)");
COMPARE(addi_d(t7, t7, -2048),
"02e00273 addi.d t7, t7, -2048(0x800)");
COMPARE(lu52i_d(a0, a0, 2047), "031ffc84 lu52i.d a0, a0, 0x7ff");
COMPARE(lu52i_d(a1, a1, -2048), "032000a5 lu52i.d a1, a1, 0x800");
COMPARE(andi(s3, a3, 0xfff), "037ffcfa andi s3, a3, 0xfff");
COMPARE(andi(a4, a4, 0), "03400108 andi a4, a4, 0x0");
COMPARE(ori(t6, t6, 0xfff), "03bffe52 ori t6, t6, 0xfff");
COMPARE(ori(t6, t6, 0), "03800252 ori t6, t6, 0x0");
COMPARE(xori(t1, t1, 0xfff), "03fffdad xori t1, t1, 0xfff");
COMPARE(xori(a3, a3, 0x0), "03c000e7 xori a3, a3, 0x0");
COMPARE(ld_b(a1, a1, 2047),
"281ffca5 ld.b a1, a1, 2047(0x7ff)");
COMPARE(ld_b(a4, a4, -2048),
"28200108 ld.b a4, a4, -2048(0x800)");
COMPARE(ld_h(a4, a0, 2047),
"285ffc88 ld.h a4, a0, 2047(0x7ff)");
COMPARE(ld_h(a4, a3, -2048),
"286000e8 ld.h a4, a3, -2048(0x800)");
COMPARE(ld_w(a6, a6, 2047),
"289ffd4a ld.w a6, a6, 2047(0x7ff)");
COMPARE(ld_w(a5, a4, -2048),
"28a00109 ld.w a5, a4, -2048(0x800)");
COMPARE(ld_d(a0, a3, 2047),
"28dffce4 ld.d a0, a3, 2047(0x7ff)");
COMPARE(ld_d(a6, fp, -2048),
"28e002ca ld.d a6, fp, -2048(0x800)");
COMPARE(ld_d(a0, a6, 0), "28c00144 ld.d a0, a6, 0(0x0)");
COMPARE(st_b(a4, a0, 2047),
"291ffc88 st.b a4, a0, 2047(0x7ff)");
COMPARE(st_b(a6, a5, -2048),
"2920012a st.b a6, a5, -2048(0x800)");
COMPARE(st_h(a4, a0, 2047),
"295ffc88 st.h a4, a0, 2047(0x7ff)");
COMPARE(st_h(t1, t2, -2048),
"296001cd st.h t1, t2, -2048(0x800)");
COMPARE(st_w(t3, a4, 2047),
"299ffd0f st.w t3, a4, 2047(0x7ff)");
COMPARE(st_w(a3, t2, -2048),
"29a001c7 st.w a3, t2, -2048(0x800)");
COMPARE(st_d(s3, sp, 2047),
"29dffc7a st.d s3, sp, 2047(0x7ff)");
COMPARE(st_d(fp, s6, -2048),
"29e003b6 st.d fp, s6, -2048(0x800)");
COMPARE(ld_bu(a6, a0, 2047),
"2a1ffc8a ld.bu a6, a0, 2047(0x7ff)");
COMPARE(ld_bu(a7, a7, -2048),
"2a20016b ld.bu a7, a7, -2048(0x800)");
COMPARE(ld_hu(a7, a7, 2047),
"2a5ffd6b ld.hu a7, a7, 2047(0x7ff)");
COMPARE(ld_hu(a3, a3, -2048),
"2a6000e7 ld.hu a3, a3, -2048(0x800)");
COMPARE(ld_wu(a3, a0, 2047),
"2a9ffc87 ld.wu a3, a0, 2047(0x7ff)");
COMPARE(ld_wu(a3, a5, -2048),
"2aa00127 ld.wu a3, a5, -2048(0x800)");
COMPARE(fld_s(f0, a3, 2047),
"2b1ffce0 fld.s f0, a3, 2047(0x7ff)");
COMPARE(fld_s(f0, a1, -2048),
"2b2000a0 fld.s f0, a1, -2048(0x800)");
COMPARE(fld_d(f0, a0, 2047),
"2b9ffc80 fld.d f0, a0, 2047(0x7ff)");
COMPARE(fld_d(f0, fp, -2048),
"2ba002c0 fld.d f0, fp, -2048(0x800)");
COMPARE(fst_d(f0, fp, 2047),
"2bdffec0 fst.d f0, fp, 2047(0x7ff)");
COMPARE(fst_d(f0, a0, -2048),
"2be00080 fst.d f0, a0, -2048(0x800)");
COMPARE(fst_s(f0, a5, 2047),
"2b5ffd20 fst.s f0, a5, 2047(0x7ff)");
COMPARE(fst_s(f0, a3, -2048),
"2b6000e0 fst.s f0, a3, -2048(0x800)");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp12) {
SET_UP();
COMPARE(fmadd_s(f0, f1, f2, f3),
"08118820 fmadd.s f0, f1, f2, f3");
COMPARE(fmadd_s(f4, f5, f6, f7),
"081398a4 fmadd.s f4, f5, f6, f7");
COMPARE(fmadd_d(f8, f9, f10, f11),
"0825a928 fmadd.d f8, f9, f10, f11");
COMPARE(fmadd_d(f12, f13, f14, f15),
"0827b9ac fmadd.d f12, f13, f14, f15");
COMPARE(fmsub_s(f0, f1, f2, f3),
"08518820 fmsub.s f0, f1, f2, f3");
COMPARE(fmsub_s(f4, f5, f6, f7),
"085398a4 fmsub.s f4, f5, f6, f7");
COMPARE(fmsub_d(f8, f9, f10, f11),
"0865a928 fmsub.d f8, f9, f10, f11");
COMPARE(fmsub_d(f12, f13, f14, f15),
"0867b9ac fmsub.d f12, f13, f14, f15");
COMPARE(fnmadd_s(f0, f1, f2, f3),
"08918820 fnmadd.s f0, f1, f2, f3");
COMPARE(fnmadd_s(f4, f5, f6, f7),
"089398a4 fnmadd.s f4, f5, f6, f7");
COMPARE(fnmadd_d(f8, f9, f10, f11),
"08a5a928 fnmadd.d f8, f9, f10, f11");
COMPARE(fnmadd_d(f12, f13, f14, f15),
"08a7b9ac fnmadd.d f12, f13, f14, f15");
COMPARE(fnmsub_s(f0, f1, f2, f3),
"08d18820 fnmsub.s f0, f1, f2, f3");
COMPARE(fnmsub_s(f4, f5, f6, f7),
"08d398a4 fnmsub.s f4, f5, f6, f7");
COMPARE(fnmsub_d(f8, f9, f10, f11),
"08e5a928 fnmsub.d f8, f9, f10, f11");
COMPARE(fnmsub_d(f12, f13, f14, f15),
"08e7b9ac fnmsub.d f12, f13, f14, f15");
COMPARE(fcmp_cond_s(CAF, f1, f2, FCC0),
"0c100820 fcmp.caf.s fcc0, f1, f2");
COMPARE(fcmp_cond_s(CUN, f5, f6, FCC0),
"0c1418a0 fcmp.cun.s fcc0, f5, f6");
COMPARE(fcmp_cond_s(CEQ, f9, f10, FCC0),
"0c122920 fcmp.ceq.s fcc0, f9, f10");
COMPARE(fcmp_cond_s(CUEQ, f13, f14, FCC0),
"0c1639a0 fcmp.cueq.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(CLT, f1, f2, FCC0),
"0c110820 fcmp.clt.s fcc0, f1, f2");
COMPARE(fcmp_cond_s(CULT, f5, f6, FCC0),
"0c1518a0 fcmp.cult.s fcc0, f5, f6");
COMPARE(fcmp_cond_s(CLE, f9, f10, FCC0),
"0c132920 fcmp.cle.s fcc0, f9, f10");
COMPARE(fcmp_cond_s(CULE, f13, f14, FCC0),
"0c1739a0 fcmp.cule.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(CNE, f1, f2, FCC0),
"0c180820 fcmp.cne.s fcc0, f1, f2");
COMPARE(fcmp_cond_s(COR, f5, f6, FCC0),
"0c1a18a0 fcmp.cor.s fcc0, f5, f6");
COMPARE(fcmp_cond_s(CUNE, f9, f10, FCC0),
"0c1c2920 fcmp.cune.s fcc0, f9, f10");
COMPARE(fcmp_cond_s(SAF, f13, f14, FCC0),
"0c10b9a0 fcmp.saf.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(SUN, f1, f2, FCC0),
"0c148820 fcmp.sun.s fcc0, f1, f2");
COMPARE(fcmp_cond_s(SEQ, f5, f6, FCC0),
"0c1298a0 fcmp.seq.s fcc0, f5, f6");
COMPARE(fcmp_cond_s(SUEQ, f9, f10, FCC0),
"0c16a920 fcmp.sueq.s fcc0, f9, f10");
// COMPARE(fcmp_cond_s(SLT, f13, f14, FCC0),
// "0c11b9a0 fcmp.slt.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(SULT, f1, f2, FCC0),
"0c158820 fcmp.sult.s fcc0, f1, f2");
COMPARE(fcmp_cond_s(SLE, f5, f6, FCC0),
"0c1398a0 fcmp.sle.s fcc0, f5, f6");
COMPARE(fcmp_cond_s(SULE, f9, f10, FCC0),
"0c17a920 fcmp.sule.s fcc0, f9, f10");
COMPARE(fcmp_cond_s(SNE, f13, f14, FCC0),
"0c18b9a0 fcmp.sne.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(SOR, f13, f14, FCC0),
"0c1ab9a0 fcmp.sor.s fcc0, f13, f14");
COMPARE(fcmp_cond_s(SUNE, f1, f2, FCC0),
"0c1c8820 fcmp.sune.s fcc0, f1, f2");
COMPARE(fcmp_cond_d(CAF, f1, f2, FCC0),
"0c200820 fcmp.caf.d fcc0, f1, f2");
COMPARE(fcmp_cond_d(CUN, f5, f6, FCC0),
"0c2418a0 fcmp.cun.d fcc0, f5, f6");
COMPARE(fcmp_cond_d(CEQ, f9, f10, FCC0),
"0c222920 fcmp.ceq.d fcc0, f9, f10");
COMPARE(fcmp_cond_d(CUEQ, f13, f14, FCC0),
"0c2639a0 fcmp.cueq.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(CLT, f1, f2, FCC0),
"0c210820 fcmp.clt.d fcc0, f1, f2");
COMPARE(fcmp_cond_d(CULT, f5, f6, FCC0),
"0c2518a0 fcmp.cult.d fcc0, f5, f6");
COMPARE(fcmp_cond_d(CLE, f9, f10, FCC0),
"0c232920 fcmp.cle.d fcc0, f9, f10");
COMPARE(fcmp_cond_d(CULE, f13, f14, FCC0),
"0c2739a0 fcmp.cule.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(CNE, f1, f2, FCC0),
"0c280820 fcmp.cne.d fcc0, f1, f2");
COMPARE(fcmp_cond_d(COR, f5, f6, FCC0),
"0c2a18a0 fcmp.cor.d fcc0, f5, f6");
COMPARE(fcmp_cond_d(CUNE, f9, f10, FCC0),
"0c2c2920 fcmp.cune.d fcc0, f9, f10");
COMPARE(fcmp_cond_d(SAF, f13, f14, FCC0),
"0c20b9a0 fcmp.saf.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(SUN, f1, f2, FCC0),
"0c248820 fcmp.sun.d fcc0, f1, f2");
COMPARE(fcmp_cond_d(SEQ, f5, f6, FCC0),
"0c2298a0 fcmp.seq.d fcc0, f5, f6");
COMPARE(fcmp_cond_d(SUEQ, f9, f10, FCC0),
"0c26a920 fcmp.sueq.d fcc0, f9, f10");
// COMPARE(fcmp_cond_d(SLT, f13, f14, FCC0),
// "0c21b9a0 fcmp.slt.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(SULT, f1, f2, FCC0),
"0c258820 fcmp.sult.d fcc0, f1, f2");
COMPARE(fcmp_cond_d(SLE, f5, f6, FCC0),
"0c2398a0 fcmp.sle.d fcc0, f5, f6");
COMPARE(fcmp_cond_d(SULE, f9, f10, FCC0),
"0c27a920 fcmp.sule.d fcc0, f9, f10");
COMPARE(fcmp_cond_d(SNE, f13, f14, FCC0),
"0c28b9a0 fcmp.sne.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(SOR, f13, f14, FCC0),
"0c2ab9a0 fcmp.sor.d fcc0, f13, f14");
COMPARE(fcmp_cond_d(SUNE, f1, f2, FCC0),
"0c2c8820 fcmp.sune.d fcc0, f1, f2");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp14) {
SET_UP();
COMPARE(alsl_w(a0, a1, a2, 1), "000418a4 alsl.w a0, a1, a2, 1");
COMPARE(alsl_w(a3, a4, a5, 3), "00052507 alsl.w a3, a4, a5, 3");
COMPARE(alsl_w(a6, a7, t0, 4), "0005b16a alsl.w a6, a7, t0, 4");
COMPARE(alsl_wu(t1, t2, t3, 1), "00063dcd alsl.wu t1, t2, t3, 1");
COMPARE(alsl_wu(t4, t5, t6, 3), "00074a30 alsl.wu t4, t5, t6, 3");
COMPARE(alsl_wu(a0, a1, a2, 4), "000798a4 alsl.wu a0, a1, a2, 4");
COMPARE(alsl_d(a3, a4, a5, 1), "002c2507 alsl.d a3, a4, a5, 1");
COMPARE(alsl_d(a6, a7, t0, 3), "002d316a alsl.d a6, a7, t0, 3");
COMPARE(alsl_d(t1, t2, t3, 4), "002dbdcd alsl.d t1, t2, t3, 4");
COMPARE(bytepick_w(t4, t5, t6, 0),
"00084a30 bytepick.w t4, t5, t6, 0");
COMPARE(bytepick_w(a0, a1, a2, 3),
"000998a4 bytepick.w a0, a1, a2, 3");
COMPARE(bytepick_d(a6, a7, t0, 0),
"000c316a bytepick.d a6, a7, t0, 0");
COMPARE(bytepick_d(t4, t5, t6, 7),
"000fca30 bytepick.d t4, t5, t6, 7");
COMPARE(slli_w(a3, a3, 31), "0040fce7 slli.w a3, a3, 31");
COMPARE(slli_w(a6, a6, 1), "0040854a slli.w a6, a6, 1");
COMPARE(slli_d(t3, t2, 63), "0041fdcf slli.d t3, t2, 63");
COMPARE(slli_d(t4, a6, 1), "00410550 slli.d t4, a6, 1");
COMPARE(srli_w(a7, a7, 31), "0044fd6b srli.w a7, a7, 31");
COMPARE(srli_w(a4, a4, 1), "00448508 srli.w a4, a4, 1");
COMPARE(srli_d(a4, a3, 63), "0045fce8 srli.d a4, a3, 63");
COMPARE(srli_d(a4, a4, 1), "00450508 srli.d a4, a4, 1");
COMPARE(srai_d(a0, a0, 63), "0049fc84 srai.d a0, a0, 63");
COMPARE(srai_d(a4, a1, 1), "004904a8 srai.d a4, a1, 1");
COMPARE(srai_w(s4, a3, 31), "0048fcfb srai.w s4, a3, 31");
COMPARE(srai_w(s4, a5, 1), "0048853b srai.w s4, a5, 1");
COMPARE(rotri_d(t7, t6, 1), "004d0653 rotri.d t7, t6, 1");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp17) {
SET_UP();
COMPARE(sltu(t5, t4, a4), "0012a211 sltu t5, t4, a4");
COMPARE(sltu(t4, zero_reg, t4),
"0012c010 sltu t4, zero_reg, t4");
COMPARE(add_w(a4, a4, a6), "00102908 add.w a4, a4, a6");
COMPARE(add_w(a5, a6, t3), "00103d49 add.w a5, a6, t3");
COMPARE(add_d(a4, t0, t1), "0010b588 add.d a4, t0, t1");
COMPARE(add_d(a6, a3, t1), "0010b4ea add.d a6, a3, t1");
COMPARE(sub_w(a7, a7, a2), "0011196b sub.w a7, a7, a2");
COMPARE(sub_w(a2, a2, s3), "001168c6 sub.w a2, a2, s3");
COMPARE(sub_d(s3, ra, s3), "0011e83a sub.d s3, ra, s3");
COMPARE(sub_d(a0, a1, a2), "001198a4 sub.d a0, a1, a2");
COMPARE(slt(a5, a5, a6), "00122929 slt a5, a5, a6");
COMPARE(slt(a6, t3, t4), "001241ea slt a6, t3, t4");
COMPARE(maskeqz(a6, a7, t0), "0013316a maskeqz a6, a7, t0");
COMPARE(maskeqz(t1, t2, t3), "00133dcd maskeqz t1, t2, t3");
COMPARE(masknez(a5, a5, a3), "00139d29 masknez a5, a5, a3");
COMPARE(masknez(a3, a4, a5), "0013a507 masknez a3, a4, a5");
COMPARE(or_(s3, sp, zero_reg),
"0015007a or s3, sp, zero_reg");
COMPARE(or_(a4, a0, zero_reg),
"00150088 or a4, a0, zero_reg");
COMPARE(and_(sp, sp, t6), "0014c863 and sp, sp, t6");
COMPARE(and_(a3, a3, a7), "0014ace7 and a3, a3, a7");
COMPARE(nor(a7, a7, a7), "00142d6b nor a7, a7, a7");
COMPARE(nor(t4, t5, t6), "00144a30 nor t4, t5, t6");
COMPARE(xor_(a0, a1, a2), "001598a4 xor a0, a1, a2");
COMPARE(xor_(a3, a4, a5), "0015a507 xor a3, a4, a5");
COMPARE(orn(a6, a7, t0), "0016316a orn a6, a7, t0");
COMPARE(orn(t1, t2, t3), "00163dcd orn t1, t2, t3");
COMPARE(andn(t4, t5, t6), "0016ca30 andn t4, t5, t6");
COMPARE(andn(a0, a1, a2), "001698a4 andn a0, a1, a2");
COMPARE(sll_w(a3, t0, a7), "00172d87 sll.w a3, t0, a7");
COMPARE(sll_w(a3, a4, a3), "00171d07 sll.w a3, a4, a3");
COMPARE(srl_w(a3, a4, a3), "00179d07 srl.w a3, a4, a3");
COMPARE(srl_w(a3, t1, t4), "0017c1a7 srl.w a3, t1, t4");
COMPARE(sra_w(a4, t4, a4), "00182208 sra.w a4, t4, a4");
COMPARE(sra_w(a3, t1, a6), "001829a7 sra.w a3, t1, a6");
COMPARE(sll_d(a3, a1, a3), "00189ca7 sll.d a3, a1, a3");
COMPARE(sll_d(a7, a4, t0), "0018b10b sll.d a7, a4, t0");
COMPARE(srl_d(a7, a7, t0), "0019316b srl.d a7, a7, t0");
COMPARE(srl_d(t0, a6, t0), "0019314c srl.d t0, a6, t0");
COMPARE(sra_d(a3, a4, a5), "0019a507 sra.d a3, a4, a5");
COMPARE(sra_d(a6, a7, t0), "0019b16a sra.d a6, a7, t0");
COMPARE(rotr_d(t1, t2, t3), "001bbdcd rotr.d t1, t2, t3");
COMPARE(rotr_d(t4, t5, t6), "001bca30 rotr.d t4, t5, t6");
COMPARE(rotr_w(a0, a1, a2), "001b18a4 rotr.w a0, a1, a2");
COMPARE(rotr_w(a3, a4, a5), "001b2507 rotr.w a3, a4, a5");
COMPARE(mul_w(t8, a5, t7), "001c4d34 mul.w t8, a5, t7");
COMPARE(mul_w(t4, t5, t6), "001c4a30 mul.w t4, t5, t6");
COMPARE(mulh_w(s3, a3, t7), "001cccfa mulh.w s3, a3, t7");
COMPARE(mulh_w(a0, a1, a2), "001c98a4 mulh.w a0, a1, a2");
COMPARE(mulh_wu(a6, a7, t0), "001d316a mulh.wu a6, a7, t0");
COMPARE(mulh_wu(t1, t2, t3), "001d3dcd mulh.wu t1, t2, t3");
COMPARE(mul_d(t2, a5, t1), "001db52e mul.d t2, a5, t1");
COMPARE(mul_d(a4, a4, a5), "001da508 mul.d a4, a4, a5");
COMPARE(mulh_d(a3, a4, a5), "001e2507 mulh.d a3, a4, a5");
COMPARE(mulh_d(a6, a7, t0), "001e316a mulh.d a6, a7, t0");
COMPARE(mulh_du(t1, t2, t3), "001ebdcd mulh.du t1, t2, t3");
COMPARE(mulh_du(t4, t5, t6), "001eca30 mulh.du t4, t5, t6");
COMPARE(mulw_d_w(a0, a1, a2), "001f18a4 mulw.d.w a0, a1, a2");
COMPARE(mulw_d_w(a3, a4, a5), "001f2507 mulw.d.w a3, a4, a5");
COMPARE(mulw_d_wu(a6, a7, t0), "001fb16a mulw.d.wu a6, a7, t0");
COMPARE(mulw_d_wu(t1, t2, t3), "001fbdcd mulw.d.wu t1, t2, t3");
COMPARE(div_w(a5, a5, a3), "00201d29 div.w a5, a5, a3");
COMPARE(div_w(t4, t5, t6), "00204a30 div.w t4, t5, t6");
COMPARE(mod_w(a6, t3, a6), "0020a9ea mod.w a6, t3, a6");
COMPARE(mod_w(a3, a4, a3), "00209d07 mod.w a3, a4, a3");
COMPARE(div_wu(t1, t2, t3), "00213dcd div.wu t1, t2, t3");
COMPARE(div_wu(t4, t5, t6), "00214a30 div.wu t4, t5, t6");
COMPARE(mod_wu(a0, a1, a2), "002198a4 mod.wu a0, a1, a2");
COMPARE(mod_wu(a3, a4, a5), "0021a507 mod.wu a3, a4, a5");
COMPARE(div_d(t0, t0, a6), "0022298c div.d t0, t0, a6");
COMPARE(div_d(a7, a7, a5), "0022256b div.d a7, a7, a5");
COMPARE(mod_d(a6, a7, t0), "0022b16a mod.d a6, a7, t0");
COMPARE(mod_d(t1, t2, t3), "0022bdcd mod.d t1, t2, t3");
COMPARE(div_du(t4, t5, t6), "00234a30 div.du t4, t5, t6");
COMPARE(div_du(a0, a1, a2), "002318a4 div.du a0, a1, a2");
COMPARE(mod_du(a3, a4, a5), "0023a507 mod.du a3, a4, a5");
COMPARE(mod_du(a6, a7, t0), "0023b16a mod.du a6, a7, t0");
COMPARE(fadd_s(f3, f4, f5), "01009483 fadd.s f3, f4, f5");
COMPARE(fadd_s(f6, f7, f8), "0100a0e6 fadd.s f6, f7, f8");
COMPARE(fadd_d(f0, f1, f0), "01010020 fadd.d f0, f1, f0");
COMPARE(fadd_d(f0, f1, f2), "01010820 fadd.d f0, f1, f2");
COMPARE(fsub_s(f9, f10, f11), "0102ad49 fsub.s f9, f10, f11");
COMPARE(fsub_s(f12, f13, f14), "0102b9ac fsub.s f12, f13, f14");
COMPARE(fsub_d(f30, f0, f30), "0103781e fsub.d f30, f0, f30");
COMPARE(fsub_d(f0, f0, f1), "01030400 fsub.d f0, f0, f1");
COMPARE(fmul_s(f15, f16, f17), "0104c60f fmul.s f15, f16, f17");
COMPARE(fmul_s(f18, f19, f20), "0104d272 fmul.s f18, f19, f20");
COMPARE(fmul_d(f0, f0, f1), "01050400 fmul.d f0, f0, f1");
COMPARE(fmul_d(f0, f0, f0), "01050000 fmul.d f0, f0, f0");
COMPARE(fdiv_s(f0, f1, f2), "01068820 fdiv.s f0, f1, f2");
COMPARE(fdiv_s(f3, f4, f5), "01069483 fdiv.s f3, f4, f5");
COMPARE(fdiv_d(f0, f0, f1), "01070400 fdiv.d f0, f0, f1");
COMPARE(fdiv_d(f0, f1, f0), "01070020 fdiv.d f0, f1, f0");
COMPARE(fmax_s(f9, f10, f11), "0108ad49 fmax.s f9, f10, f11");
COMPARE(fmin_s(f6, f7, f8), "010aa0e6 fmin.s f6, f7, f8");
COMPARE(fmax_d(f0, f1, f0), "01090020 fmax.d f0, f1, f0");
COMPARE(fmin_d(f0, f1, f0), "010b0020 fmin.d f0, f1, f0");
COMPARE(fmaxa_s(f12, f13, f14), "010cb9ac fmaxa.s f12, f13, f14");
COMPARE(fmina_s(f15, f16, f17), "010ec60f fmina.s f15, f16, f17");
COMPARE(fmaxa_d(f18, f19, f20), "010d5272 fmaxa.d f18, f19, f20");
COMPARE(fmina_d(f0, f1, f2), "010f0820 fmina.d f0, f1, f2");
COMPARE(ldx_b(a0, a1, a2), "380018a4 ldx.b a0, a1, a2");
COMPARE(ldx_h(a3, a4, a5), "38042507 ldx.h a3, a4, a5");
COMPARE(ldx_w(a6, a7, t0), "3808316a ldx.w a6, a7, t0");
COMPARE(stx_b(t1, t2, t3), "38103dcd stx.b t1, t2, t3");
COMPARE(stx_h(t4, t5, t6), "38144a30 stx.h t4, t5, t6");
COMPARE(stx_w(a0, a1, a2), "381818a4 stx.w a0, a1, a2");
COMPARE(ldx_bu(a3, a4, a5), "38202507 ldx.bu a3, a4, a5");
COMPARE(ldx_hu(a6, a7, t0), "3824316a ldx.hu a6, a7, t0");
COMPARE(ldx_wu(t1, t2, t3), "38283dcd ldx.wu t1, t2, t3");
COMPARE(ldx_d(a2, s6, t6), "380c4ba6 ldx.d a2, s6, t6");
COMPARE(ldx_d(t7, s6, t6), "380c4bb3 ldx.d t7, s6, t6");
COMPARE(stx_d(a4, a3, t6), "381c48e8 stx.d a4, a3, t6");
COMPARE(stx_d(a0, a3, t6), "381c48e4 stx.d a0, a3, t6");
COMPARE(dbar(0), "38720000 dbar 0x0(0)");
COMPARE(ibar(5555), "387295b3 ibar 0x15b3(5555)");
COMPARE(break_(0), "002a0000 break code: 0x0(0)");
COMPARE(break_(0x3fc0), "002a3fc0 break code: 0x3fc0(16320)");
COMPARE(fldx_s(f3, a4, a5), "38302503 fldx.s f3, a4, a5");
COMPARE(fldx_d(f6, a7, t0), "38343166 fldx.d f6, a7, t0");
COMPARE(fstx_s(f1, t2, t3), "38383dc1 fstx.s f1, t2, t3");
COMPARE(fstx_d(f4, t5, t6), "383c4a24 fstx.d f4, t5, t6");
COMPARE(amswap_w(a4, a5, a6), "38602548 amswap.w a4, a5, a6");
COMPARE(amswap_d(a7, t0, t1), "3860b1ab amswap.d a7, t0, t1");
COMPARE(amadd_w(t2, t3, t4), "38613e0e amadd.w t2, t3, t4");
COMPARE(amadd_d(t5, t6, a0), "3861c891 amadd.d t5, t6, a0");
COMPARE(amand_w(a1, a2, a3), "386218e5 amand.w a1, a2, a3");
COMPARE(amand_d(a4, a5, a6), "3862a548 amand.d a4, a5, a6");
COMPARE(amor_w(a7, t0, t1), "386331ab amor.w a7, t0, t1");
COMPARE(amor_d(t2, t3, t4), "3863be0e amor.d t2, t3, t4");
COMPARE(amxor_w(t5, t6, a0), "38644891 amxor.w t5, t6, a0");
COMPARE(amxor_d(a1, a2, a3), "386498e5 amxor.d a1, a2, a3");
COMPARE(ammax_w(a4, a5, a6), "38652548 ammax.w a4, a5, a6");
COMPARE(ammax_d(a7, t0, t1), "3865b1ab ammax.d a7, t0, t1");
COMPARE(ammin_w(t2, t3, t4), "38663e0e ammin.w t2, t3, t4");
COMPARE(ammin_d(t5, t6, a0), "3866c891 ammin.d t5, t6, a0");
COMPARE(ammax_wu(a1, a2, a3), "386718e5 ammax.wu a1, a2, a3");
COMPARE(ammax_du(a4, a5, a6), "3867a548 ammax.du a4, a5, a6");
COMPARE(ammin_wu(a7, t0, t1), "386831ab ammin.wu a7, t0, t1");
COMPARE(ammin_du(t2, t3, t4), "3868be0e ammin.du t2, t3, t4");
COMPARE(ammax_db_d(a0, a1, a2), "386e94c4 ammax_db.d a0, a1, a2");
COMPARE(ammax_db_du(a3, a4, a5), "3870a127 ammax_db.du a3, a4, a5");
COMPARE(ammax_db_w(a6, a7, t0), "386e2d8a ammax_db.w a6, a7, t0");
COMPARE(ammax_db_wu(t1, t2, t3), "387039ed ammax_db.wu t1, t2, t3");
COMPARE(ammin_db_d(t4, t5, t6), "386fc650 ammin_db.d t4, t5, t6");
COMPARE(ammin_db_du(a0, a1, a2), "387194c4 ammin_db.du a0, a1, a2");
COMPARE(ammin_db_wu(a3, a4, a5), "38712127 ammin_db.wu a3, a4, a5");
COMPARE(ammin_db_w(a6, a7, t0), "386f2d8a ammin_db.w a6, a7, t0");
COMPARE(fscaleb_s(f0, f1, f2), "01108820 fscaleb.s f0, f1, f2");
COMPARE(fscaleb_d(f3, f4, f5), "01111483 fscaleb.d f3, f4, f5");
COMPARE(fcopysign_s(f6, f7, f8), "0112a0e6 fcopysign.s f6, f7, f8");
COMPARE(fcopysign_d(f9, f10, f12),
"01133149 fcopysign.d f9, f10, f12");
VERIFY_RUN();
}
TEST_F(DisasmLoong64Test, TypeOp22) {
SET_UP();
COMPARE(clz_w(a3, a0), "00001487 clz.w a3, a0");
COMPARE(ctz_w(a0, a1), "00001ca4 ctz.w a0, a1");
COMPARE(clz_d(a2, a3), "000024e6 clz.d a2, a3");
COMPARE(ctz_d(a4, a5), "00002d28 ctz.d a4, a5");
COMPARE(clo_w(a0, a1), "000010a4 clo.w a0, a1");
COMPARE(cto_w(a2, a3), "000018e6 cto.w a2, a3");
COMPARE(clo_d(a4, a5), "00002128 clo.d a4, a5");
COMPARE(cto_d(a6, a7), "0000296a cto.d a6, a7");
COMPARE(revb_2h(a6, a7), "0000316a revb.2h a6, a7");
COMPARE(revb_4h(t0, t1), "000035ac revb.4h t0, t1");
COMPARE(revb_2w(t2, t3), "000039ee revb.2w t2, t3");
COMPARE(revb_d(t4, t5), "00003e30 revb.d t4, t5");
COMPARE(revh_2w(a0, a1), "000040a4 revh.2w a0, a1");
COMPARE(revh_d(a2, a3), "000044e6 revh.d a2, a3");
COMPARE(bitrev_4b(a4, a5), "00004928 bitrev.4b a4, a5");
COMPARE(bitrev_8b(a6, a7), "00004d6a bitrev.8b a6, a7");
COMPARE(bitrev_w(t0, t1), "000051ac bitrev.w t0, t1");
COMPARE(bitrev_d(t2, t3), "000055ee bitrev.d t2, t3");
COMPARE(ext_w_b(t4, t5), "00005e30 ext.w.b t4, t5");
COMPARE(ext_w_h(a0, a1), "000058a4 ext.w.h a0, a1");
COMPARE(fabs_s(f2, f3), "01140462 fabs.s f2, f3");
COMPARE(fabs_d(f0, f0), "01140800 fabs.d f0, f0");
COMPARE(fneg_s(f0, f1), "01141420 fneg.s f0, f1");
COMPARE(fneg_d(f0, f0), "01141800 fneg.d f0, f0");
COMPARE(fsqrt_s(f4, f5), "011444a4 fsqrt.s f4, f5");
COMPARE(fsqrt_d(f0, f0), "01144800 fsqrt.d f0, f0");
COMPARE(fmov_s(f6, f7), "011494e6 fmov.s f6, f7");
COMPARE(fmov_d(f0, f1), "01149820 fmov.d f0, f1");
COMPARE(fmov_d(f1, f0), "01149801 fmov.d f1, f0");
COMPARE(movgr2fr_d(f0, t6), "0114aa40 movgr2fr.d f0, t6");
COMPARE(movgr2fr_d(f1, t6), "0114aa41 movgr2fr.d f1, t6");
COMPARE(movgr2fr_w(f30, a3), "0114a4fe movgr2fr.w f30, a3");
COMPARE(movgr2fr_w(f30, a0), "0114a49e movgr2fr.w f30, a0");
COMPARE(movgr2frh_w(f30, t6), "0114ae5e movgr2frh.w f30, t6");
COMPARE(movgr2frh_w(f0, a3), "0114ace0 movgr2frh.w f0, a3");
COMPARE(movfr2gr_s(a3, f30), "0114b7c7 movfr2gr.s a3, f30");
COMPARE(movfr2gr_d(a6, f30), "0114bbca movfr2gr.d a6, f30");
COMPARE(movfr2gr_d(t7, f30), "0114bbd3 movfr2gr.d t7, f30");
COMPARE(movfrh2gr_s(a5, f0), "0114bc09 movfrh2gr.s a5, f0");
COMPARE(movfrh2gr_s(a4, f0), "0114bc08 movfrh2gr.s a4, f0");
COMPARE(movgr2fcsr(a2), "0114c0c0 movgr2fcsr fcsr, a2");
COMPARE(movfcsr2gr(a4), "0114c808 movfcsr2gr a4, fcsr");
COMPARE(movfr2cf(FCC0, f0), "0114d000 movfr2cf fcc0, f0");
COMPARE(movcf2fr(f1, FCC1), "0114d421 movcf2fr f1, fcc1");
COMPARE(movgr2cf(FCC2, a0), "0114d882 movgr2cf fcc2, a0");
COMPARE(movcf2gr(a1, FCC3), "0114dc65 movcf2gr a1, fcc3");
COMPARE(fcvt_s_d(f0, f0), "01191800 fcvt.s.d f0, f0");
COMPARE(fcvt_d_s(f0, f0), "01192400 fcvt.d.s f0, f0");
COMPARE(ftintrm_w_s(f8, f9), "011a0528 ftintrm.w.s f8, f9");
COMPARE(ftintrm_w_d(f10, f11), "011a096a ftintrm.w.d f10, f11");
COMPARE(ftintrm_l_s(f12, f13), "011a25ac ftintrm.l.s f12, f13");
COMPARE(ftintrm_l_d(f14, f15), "011a29ee ftintrm.l.d f14, f15");
COMPARE(ftintrp_w_s(f16, f17), "011a4630 ftintrp.w.s f16, f17");
COMPARE(ftintrp_w_d(f18, f19), "011a4a72 ftintrp.w.d f18, f19");
COMPARE(ftintrp_l_s(f20, f21), "011a66b4 ftintrp.l.s f20, f21");
COMPARE(ftintrp_l_d(f0, f1), "011a6820 ftintrp.l.d f0, f1");
COMPARE(ftintrz_w_s(f30, f4), "011a849e ftintrz.w.s f30, f4");
COMPARE(ftintrz_w_d(f30, f4), "011a889e ftintrz.w.d f30, f4");
COMPARE(ftintrz_l_s(f30, f0), "011aa41e ftintrz.l.s f30, f0");
COMPARE(ftintrz_l_d(f30, f30), "011aabde ftintrz.l.d f30, f30");
COMPARE(ftintrne_w_s(f2, f3), "011ac462 ftintrne.w.s f2, f3");
COMPARE(ftintrne_w_d(f4, f5), "011ac8a4 ftintrne.w.d f4, f5");
COMPARE(ftintrne_l_s(f6, f7), "011ae4e6 ftintrne.l.s f6, f7");
COMPARE(ftintrne_l_d(f8, f9), "011ae928 ftintrne.l.d f8, f9");
COMPARE(ftint_w_s(f10, f11), "011b056a ftint.w.s f10, f11");
COMPARE(ftint_w_d(f12, f13), "011b09ac ftint.w.d f12, f13");
COMPARE(ftint_l_s(f14, f15), "011b25ee ftint.l.s f14, f15");
COMPARE(ftint_l_d(f16, f17), "011b2a30 ftint.l.d f16, f17");
COMPARE(ffint_s_w(f18, f19), "011d1272 ffint.s.w f18, f19");
COMPARE(ffint_s_l(f20, f21), "011d1ab4 ffint.s.l f20, f21");
COMPARE(ffint_d_w(f0, f1), "011d2020 ffint.d.w f0, f1");
COMPARE(ffint_d_l(f2, f3), "011d2862 ffint.d.l f2, f3");
COMPARE(frint_s(f4, f5), "011e44a4 frint.s f4, f5");
COMPARE(frint_d(f6, f7), "011e48e6 frint.d f6, f7");
COMPARE(frecip_s(f8, f9), "01145528 frecip.s f8, f9");
COMPARE(frecip_d(f10, f11), "0114596a frecip.d f10, f11");
COMPARE(frsqrt_s(f12, f13), "011465ac frsqrt.s f12, f13");
COMPARE(frsqrt_d(f14, f15), "011469ee frsqrt.d f14, f15");
COMPARE(fclass_s(f16, f17), "01143630 fclass.s f16, f17");
COMPARE(fclass_d(f18, f19), "01143a72 fclass.d f18, f19");
COMPARE(flogb_s(f20, f21), "011426b4 flogb.s f20, f21");
COMPARE(flogb_d(f0, f1), "01142820 flogb.d f0, f1");
VERIFY_RUN();
}
} // namespace internal
} // namespace v8

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,156 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <stdlib.h>
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using DisasmPpcTest = TestWithIsolate;
bool DisassembleAndCompare(uint8_t* pc, const char* compare_string) {
disasm::NameConverter converter;
disasm::Disassembler disasm(converter);
base::EmbeddedVector<char, 128> disasm_buffer;
disasm.InstructionDecode(disasm_buffer, pc);
if (strcmp(compare_string, disasm_buffer.begin()) != 0) {
fprintf(stderr,
"expected: \n"
"%s\n"
"disassembled: \n"
"%s\n\n",
compare_string, disasm_buffer.begin());
return false;
}
return true;
}
// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
#define SET_UP() \
HandleScope scope(isolate()); \
uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(4 * 1024)); \
Assembler assm(AssemblerOptions{}, \
ExternalAssemblerBuffer(buffer, 4 * 1024)); \
bool failure = false;
// This macro assembles one instruction using the preallocated assembler and
// disassembles the generated instruction, comparing the output to the expected
// value. If the comparison fails an error message is printed, but the test
// continues to run until the end.
#define COMPARE(asm_, compare_string) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
}
// Force emission of any pending literals into a pool.
#define EMIT_PENDING_LITERALS() assm.CheckConstPool(true, false)
// Verify that all invocations of the COMPARE macro passed successfully.
// Exit with a failure if at least one of the tests failed.
#define VERIFY_RUN() \
if (failure) { \
FATAL("PPC Disassembler tests failed.\n"); \
}
TEST_F(DisasmPpcTest, DisasmPPC) {
SET_UP();
COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9");
COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20");
COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, ip, 63");
COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0");
COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0");
COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4");
COMPARE(and_(r3, r6, r5), "7cc32838 and r3, r6, r5");
COMPARE(and_(r6, r0, r6, SetRC), "7c063039 and. r6, r0, r6");
// skipping branches (for now?)
COMPARE(bctr(), "4e800420 bctr");
COMPARE(bctrl(), "4e800421 bctrl");
COMPARE(blr(), "4e800020 blr");
// skipping call - only used in simulator
#if V8_TARGET_ARCH_PPC64
COMPARE(cmpi(r0, Operand(5)), "2c200005 cmpi r0, 5");
#else
COMPARE(cmpi(r0, Operand(5)), "2f800005 cmpi r0, 5");
#endif
#if V8_TARGET_ARCH_PPC64
COMPARE(cmpl(r6, r7), "7c263840 cmpl r6, r7");
#else
COMPARE(cmpl(r6, r7), "7f863840 cmpl r6, r7");
#endif
#if V8_TARGET_ARCH_PPC64
COMPARE(cmp(r5, r11), "7c255800 cmp r5, r11");
#else
COMPARE(cmp(r5, r11), "7f855800 cmp r5, r11");
#endif
// skipping crxor - incomplete disassembly
COMPARE(lbz(r4, MemOperand(r4, 7)), "88840007 lbz r4, 7(r4)");
COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)");
COMPARE(li(r0, Operand(16)), "38000010 li r0, 16");
COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560");
COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz ip, 44(r19)");
COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, ip");
COMPARE(mflr(r0), "7c0802a6 mflr r0");
COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4");
COMPARE(mtctr(r0), "7c0903a6 mtctr r0");
COMPARE(mtlr(r15), "7de803a6 mtlr r15");
COMPARE(ori(r8, r8, Operand(42849)), "6108a761 ori r8, r8, 42849");
COMPARE(orx(r5, r3, r4), "7c652378 or r5, r3, r4");
COMPARE(rlwinm(r4, r3, 2, 0, 29), "5464103a rlwinm r4, r3, 2, 0, 29");
COMPARE(rlwinm(r0, r3, 0, 31, 31, SetRC),
"546007ff rlwinm. r0, r3, 0, 31, 31");
COMPARE(srawi(r3, r6, 1), "7cc30e70 srawi r3,r6,1");
COMPARE(stb(r5, MemOperand(r11, 11)), "98ab000b stb r5, 11(r11)");
COMPARE(stfd(d2, MemOperand(sp, 8)), "d8410008 stfd d2, 8(sp)");
COMPARE(stw(r16, MemOperand(sp, 64)), "92010040 stw r16, 64(sp)");
COMPARE(stwu(r3, MemOperand(sp, -4)), "9461fffc stwu r3, -4(sp)");
COMPARE(sub(r3, r3, r4), "7c641850 subf r3, r4, r3");
COMPARE(sub(r0, r9, r8, LeaveOE, SetRC), "7c084851 subf. r0, r8, r9");
COMPARE(xor_(r6, r5, r4), "7ca62278 xor r6, r5, r4");
VERIFY_RUN();
}
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,749 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <stdlib.h>
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using DisasmRiscvTest = TestWithIsolate;
bool prev_instr_compact_branch = false;
bool DisassembleAndCompare(uint8_t* pc, const char* compare_string) {
disasm::NameConverter converter;
disasm::Disassembler disasm(converter);
base::EmbeddedVector<char, 128> disasm_buffer;
if (prev_instr_compact_branch) {
disasm.InstructionDecode(disasm_buffer, pc);
pc += 4;
}
disasm.InstructionDecode(disasm_buffer, pc);
if (strcmp(compare_string, disasm_buffer.begin()) != 0) {
fprintf(stderr,
"expected: \n"
"%s\n"
"disassembled: \n"
"%s\n\n",
compare_string, disasm_buffer.begin());
return false;
}
return true;
}
// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
#define SET_UP() \
HandleScope scope(isolate()); \
uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(4 * 1024)); \
Assembler assm(AssemblerOptions{}, \
ExternalAssemblerBuffer(buffer, 4 * 1024)); \
bool failure = false;
// This macro assembles one instruction using the preallocated assembler and
// disassembles the generated instruction, comparing the output to the expected
// value. If the comparison fails an error message is printed, but the test
// continues to run until the end.
#define COMPARE(asm_, compare_string) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
}
#define COMPARE_PC_REL(asm_, compare_string, offset) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
char str_with_address[100]; \
snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
compare_string, static_cast<void*>(progcounter + (offset))); \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
}
// Verify that all invocations of the COMPARE macro passed successfully.
// Exit with a failure if at least one of the tests failed.
#define VERIFY_RUN() \
if (failure) { \
FATAL("RISCV Disassembler tests failed.\n"); \
}
TEST_F(DisasmRiscvTest, Arith) {
SET_UP();
// Arithmetic with immediate
COMPARE(addi(t6, s3, -268), "ef498f93 addi t6, s3, -268");
COMPARE(slti(t5, s4, -268), "ef4a2f13 slti t5, s4, -268");
COMPARE(sltiu(t4, s5, -268), "ef4abe93 sltiu t4, s5, -268");
COMPARE(xori(t3, s6, static_cast<int16_t>(0xfffffef4)),
"ef4b4e13 xori t3, s6, 0xfffffef4");
COMPARE(ori(s11, zero_reg, static_cast<int16_t>(0xfffffef4)),
"ef406d93 ori s11, zero_reg, 0xfffffef4");
COMPARE(andi(s10, ra, static_cast<int16_t>(0xfffffef4)),
"ef40fd13 andi s10, ra, 0xfffffef4");
COMPARE(slli(s9, sp, 17), "01111c93 slli s9, sp, 17");
COMPARE(srli(s8, gp, 17), "0111dc13 srli s8, gp, 17");
COMPARE(srai(s7, tp, 17), "41125b93 srai s7, tp, 17");
// Arithmetic
COMPARE(add(s6, t0, t4), "01d28b33 add s6, t0, t4");
COMPARE(sub(s5, t1, s4), "41430ab3 sub s5, t1, s4");
COMPARE(sll(s4, t2, s4), "01439a33 sll s4, t2, s4");
COMPARE(slt(s3, fp, s4), "014429b3 slt s3, fp, s4");
COMPARE(sltu(s2, s3, t6), "01f9b933 sltu s2, s3, t6");
COMPARE(xor_(a7, s4, s4), "014a48b3 xor a7, s4, s4");
COMPARE(srl(a6, s5, s4), "014ad833 srl a6, s5, s4");
COMPARE(sra(a0, s3, s4), "4149d533 sra a0, s3, s4");
COMPARE(or_(a0, s3, s4), "0149e533 or a0, s3, s4");
COMPARE(and_(a0, s3, s4), "0149f533 and a0, s3, s4");
VERIFY_RUN();
}
TEST_F(DisasmRiscvTest, RVB) {
SET_UP();
COMPARE(sh1add(s6, t1, t5), "21e32b33 sh1add s6, t1, t5");
COMPARE(sh2add(s7, t1, t2), "20734bb3 sh2add s7, t1, t2");
COMPARE(sh3add(s4, t1, t3), "21c36a33 sh3add s4, t1, t3");
#ifdef V8_TARGET_ARCH_RISCV64
COMPARE(adduw(s6, t1, t5), "09e30b3b add.uw s6, t1, t5");
COMPARE(zextw(s6, t1), "08030b3b zext.w s6, t1");
COMPARE(sh1adduw(s6, t1, t5), "21e32b3b sh1add.uw s6, t1, t5");
COMPARE(sh2adduw(s7, t1, t2), "20734bbb sh2add.uw s7, t1, t2");
COMPARE(sh3adduw(s4, t1, t3), "21c36a3b sh3add.uw s4, t1, t3");
COMPARE(slliuw(s6, t1, 10), "08a31b1b slli.uw s6, t1, 10");
#endif
COMPARE(andn(a0, s3, s4), "4149f533 andn a0, s3, s4");
COMPARE(orn(a0, s3, s4), "4149e533 orn a0, s3, s4");
COMPARE(xnor(a0, s3, s4), "4149c533 xnor a0, s3, s4");
COMPARE(clz(a0, s3), "60099513 clz a0, s3");
COMPARE(ctz(a0, s3), "60199513 ctz a0, s3");
#ifdef V8_TARGET_ARCH_RISCV64
COMPARE(clzw(a1, s3), "6009959b clzw a1, s3");
COMPARE(ctzw(a0, s2), "6019151b ctzw a0, s2");
#endif
COMPARE(max(a1, s3, t0), "0a59e5b3 max a1, s3, t0");
COMPARE(maxu(a0, s2, a1), "0ab97533 maxu a0, s2, a1");
COMPARE(min(a1, s3, fp), "0a89c5b3 min a1, s3, fp");
COMPARE(minu(a0, s2, sp), "0a295533 minu a0, s2, sp");
COMPARE(sextb(a0, s2), "60491513 sext.b a0, s2");
COMPARE(sexth(a1, s3), "60599593 sext.h a1, s3");
#ifdef V8_TARGET_ARCH_RISCV64
COMPARE(zexth(a0, s2), "0809453b zext.h a0, s2");
COMPARE(rev8(a0, s2), "6b895513 rev8 a0, s2");
#else
COMPARE(zexth(a0, s2), "08094533 zext.h a0, s2");
COMPARE(rev8(a0, s2), "69895513 rev8 a0, s2");
#endif
COMPARE(rol(a0, s3, s4), "61499533 rol a0, s3, s4");
COMPARE(ror(a0, s3, s4), "6149d533 ror a0, s3, s4");
COMPARE(orcb(a0, s3), "2879d513 orc.b a0, s3");
#ifdef V8_TARGET_ARCH_RISCV64
COMPARE(rori(a0, s3, 63), "63f9d513 rori a0, s3, 63");
COMPARE(roriw(a0, s3, 31), "61f9d51b roriw a0, s3, 31");
COMPARE(rolw(a0, s3, s4), "6149953b rolw a0, s3, s4");
COMPARE(rorw(a0, s3, s4), "6149d53b rorw a0, s3, s4");
#else
COMPARE(rori(a0, s3, 31), "61f9d513 rori a0, s3, 31");
#endif
COMPARE(bclr(a0, s2, s1), "48991533 bclr a0, s2, s1");
COMPARE(bclri(a0, s1, 3), "48349513 bclri a0, s1, 3");
COMPARE(bext(a0, s2, s1), "48995533 bext a0, s2, s1");
COMPARE(bexti(a0, s1, 3), "4834d513 bexti a0, s1, 3");
COMPARE(binv(a0, s2, s1), "68991533 binv a0, s2, s1");
COMPARE(binvi(a0, s1, 3), "68349513 binvi a0, s1, 3");
COMPARE(bset(a0, s2, s1), "28991533 bset a0, s2, s1");
COMPARE(bseti(a0, s1, 3), "28349513 bseti a0, s1, 3");
VERIFY_RUN();
}
TEST_F(DisasmRiscvTest, LD_ST) {
SET_UP();
// Loads
COMPARE(lb(t0, a0, 0), "00050283 lb t0, 0(a0)");
COMPARE(lh(t1, a1, -1024), "c0059303 lh t1, -1024(a1)");
COMPARE(lw(t2, a2, 100), "06462383 lw t2, 100(a2)");
COMPARE(lbu(fp, a3, -512), "e006c403 lbu fp, -512(a3)");
COMPARE(lhu(s1, a4, 258), "10275483 lhu s1, 258(a4)");
// Stores
COMPARE(sb(zero_reg, a5, -4), "fe078e23 sb zero_reg, -4(a5)");
COMPARE(sh(a6, s2, 4), "01091223 sh a6, 4(s2)");
COMPARE(sw(a7, s3, 100), "0719a223 sw a7, 100(s3)");
VERIFY_RUN();
}
TEST_F(DisasmRiscvTest, MISC) {
SET_UP();
COMPARE(lui(sp, 0x64), "00064137 lui sp, 0x64");
COMPARE(auipc(ra, 0x7fe), "007fe097 auipc ra, 0x7fe");
// Jumps
COMPARE_PC_REL(jal(gp, 100), "064001ef jal gp, 100", 100);
COMPARE(jalr(tp, zero_reg, 100),
"06400267 jalr tp, 100(zero_reg)");
// Branches
COMPARE_PC_REL(beq(fp, a4, -268), "eee40ae3 beq fp, a4, -268",
-268);
COMPARE_PC_REL(bne(t1, s4, -268), "ef431ae3 bne t1, s4, -268",
-268);
COMPARE_PC_REL(blt(s3, t4, -268), "efd9cae3 blt s3, t4, -268",
-268);
COMPARE_PC_REL(bge(t2, sp, -268), "ee23dae3 bge t2, sp, -268",
-268);
COMPARE_PC_REL(bltu(s6, a1, -268), "eebb6ae3 bltu s6, a1, -268",
-268);
COMPARE_PC_REL(bgeu(a1, s3, -268), "ef35fae3 bgeu a1, s3, -268",
-268);
// Memory fences
COMPARE(fence(PSO | PSR, PSW | PSI), "0690000f fence or, iw");
COMPARE(fence_tso(), "8330000f fence rw, rw");
// Environment call / break
COMPARE(ecall(), "00000073 ecall");
COMPARE(ebreak(), "00100073 ebreak");
VERIFY_RUN();
}
TEST_F(DisasmRiscvTest, CSR) {
SET_UP();
COMPARE(csrrw(a0, csr_fflags, t3), "001e1573 fsflags a0, t3");
COMPARE(csrrs(a0, csr_frm, t1), "00232573 csrrs a0, csr_frm, t1");
COMPARE(csrrc(a0, csr_fcsr, s3), "0039b573 csrrc a0, csr_fcsr, s3");
COMPARE(csrrwi(a0, csr_fflags, 0x10),
"00185573 csrrwi a0, csr_fflags, 0x10");
COMPARE(csrrsi(t3, csr_frm, 0x3),
"0021ee73 csrrsi t3, csr_frm, 0x3");
COMPARE(csrrci(a0, csr_fflags, 0x10),
"00187573 csrrci a0, csr_fflags, 0x10");
VERIFY_RUN();
}
TEST_F(DisasmRiscvTest, ZICOND) {
SET_UP();
COMPARE(czero_eqz(a0, s1, t3), "0fc4d533 czero.eqz a0, s1, t3");
COMPARE(czero_nez(s3, a1, t1), "0e65f9b3 czero.nez s3, a1, t1");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64I) {
SET_UP();
COMPARE(lwu(a0, s3, -268), "ef49e503 lwu a0, -268(s3)");
COMPARE(ld(a1, s3, -268), "ef49b583 ld a1, -268(s3)");
COMPARE(sd(fp, sp, -268), "ee813a23 sd fp, -268(sp)");
COMPARE(addiw(gp, s3, -268), "ef49819b addiw gp, s3, -268");
COMPARE(slliw(tp, s3, 17), "0119921b slliw tp, s3, 17");
COMPARE(srliw(ra, s3, 10), "00a9d09b srliw ra, s3, 10");
COMPARE(sraiw(sp, s3, 17), "4119d11b sraiw sp, s3, 17");
COMPARE(addw(t1, zero_reg, s4), "0140033b addw t1, zero_reg, s4");
COMPARE(subw(t2, s3, s4), "414983bb subw t2, s3, s4");
COMPARE(sllw(s7, s3, s4), "01499bbb sllw s7, s3, s4");
COMPARE(srlw(s10, s3, s4), "0149dd3b srlw s10, s3, s4");
COMPARE(sraw(a7, s3, s4), "4149d8bb sraw a7, s3, s4");
VERIFY_RUN();
}
#endif
TEST_F(DisasmRiscvTest, RV32M) {
SET_UP();
COMPARE(mul(a0, s3, t4), "03d98533 mul a0, s3, t4");
COMPARE(mulh(a0, s3, t4), "03d99533 mulh a0, s3, t4");
COMPARE(mulhsu(a0, s3, t4), "03d9a533 mulhsu a0, s3, t4");
COMPARE(mulhu(a0, s3, t4), "03d9b533 mulhu a0, s3, t4");
COMPARE(div(a0, s3, t4), "03d9c533 div a0, s3, t4");
COMPARE(divu(a0, s3, t4), "03d9d533 divu a0, s3, t4");
COMPARE(rem(a0, s3, t4), "03d9e533 rem a0, s3, t4");
COMPARE(remu(a0, s3, t4), "03d9f533 remu a0, s3, t4");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64M) {
SET_UP();
COMPARE(mulw(a0, s3, s4), "0349853b mulw a0, s3, s4");
COMPARE(divw(a0, s3, s4), "0349c53b divw a0, s3, s4");
COMPARE(divuw(a0, s3, s4), "0349d53b divuw a0, s3, s4");
COMPARE(remw(a0, s3, s4), "0349e53b remw a0, s3, s4");
COMPARE(remuw(a0, s3, s4), "0349f53b remuw a0, s3, s4");
VERIFY_RUN();
}
#endif
TEST_F(DisasmRiscvTest, RV32A) {
SET_UP();
// RV32A Standard Extension
COMPARE(lr_w(true, false, a0, s3), "1409a52f lr.w.aq a0, (s3)");
COMPARE(sc_w(true, true, a0, s3, s4),
"1f49a52f sc.w.aqrl a0, s4, (s3)");
COMPARE(amoswap_w(false, false, a0, s3, s4),
"0949a52f amoswap.w a0, s4, (s3)");
COMPARE(amoadd_w(false, true, a0, s3, s4),
"0349a52f amoadd.w.rl a0, s4, (s3)");
COMPARE(amoxor_w(true, false, a0, s3, s4),
"2549a52f amoxor.w.aq a0, s4, (s3)");
COMPARE(amoand_w(false, false, a0, s3, s4),
"6149a52f amoand.w a0, s4, (s3)");
COMPARE(amoor_w(true, true, a0, s3, s4),
"4749a52f amoor.w.aqrl a0, s4, (s3)");
COMPARE(amomin_w(false, true, a0, s3, s4),
"8349a52f amomin.w.rl a0, s4, (s3)");
COMPARE(amomax_w(true, false, a0, s3, s4),
"a549a52f amomax.w.aq a0, s4, (s3)");
COMPARE(amominu_w(false, false, a0, s3, s4),
"c149a52f amominu.w a0, s4, (s3)");
COMPARE(amomaxu_w(true, true, a0, s3, s4),
"e749a52f amomaxu.w.aqrl a0, s4, (s3)");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64A) {
SET_UP();
COMPARE(lr_d(true, true, a0, s3), "1609b52f lr.d.aqrl a0, (s3)");
COMPARE(sc_d(false, true, a0, s3, s4), "1b49b52f sc.d.rl a0, s4, (s3)");
COMPARE(amoswap_d(true, false, a0, s3, s4),
"0d49b52f amoswap.d.aq a0, s4, (s3)");
COMPARE(amoadd_d(false, false, a0, s3, s4),
"0149b52f amoadd.d a0, s4, (s3)");
COMPARE(amoxor_d(true, false, a0, s3, s4),
"2549b52f amoxor.d.aq a0, s4, (s3)");
COMPARE(amoand_d(true, true, a0, s3, s4),
"6749b52f amoand.d.aqrl a0, s4, (s3)");
COMPARE(amoor_d(false, true, a0, s3, s4),
"4349b52f amoor.d.rl a0, s4, (s3)");
COMPARE(amomin_d(true, true, a0, s3, s4),
"8749b52f amomin.d.aqrl a0, s4, (s3)");
COMPARE(amomax_d(false, true, a0, s3, s4),
"a349b52f amomax.d.rl a0, s4, (s3)");
COMPARE(amominu_d(true, false, a0, s3, s4),
"c549b52f amominu.d.aq a0, s4, (s3)");
COMPARE(amomaxu_d(false, true, a0, s3, s4),
"e349b52f amomaxu.d.rl a0, s4, (s3)");
VERIFY_RUN();
}
#endif
TEST_F(DisasmRiscvTest, RV32F) {
SET_UP();
// RV32F Standard Extension
COMPARE(flw(fa0, s3, -268), "ef49a507 flw fa0, -268(s3)");
COMPARE(fsw(ft7, sp, -268), "ee712a27 fsw ft7, -268(sp)");
COMPARE(fmadd_s(fa0, ft8, fa5, fs5),
"a8fe0543 fmadd.s fa0, ft8, fa5, fs5");
COMPARE(fmsub_s(fa0, ft8, fa5, fs5),
"a8fe0547 fmsub.s fa0, ft8, fa5, fs5");
COMPARE(fnmsub_s(fa0, ft8, fa5, fs5),
"a8fe054b fnmsub.s fa0, ft8, fa5, fs5");
COMPARE(fnmadd_s(fa0, ft8, fa5, fs5),
"a8fe054f fnmadd.s fa0, ft8, fa5, fs5");
COMPARE(fadd_s(fa0, ft8, fa5), "00fe0553 fadd.s fa0, ft8, fa5");
COMPARE(fsub_s(fa0, ft8, fa5), "08fe0553 fsub.s fa0, ft8, fa5");
COMPARE(fmul_s(fa0, ft8, fa5), "10fe0553 fmul.s fa0, ft8, fa5");
COMPARE(fdiv_s(ft0, ft8, fa5), "18fe0053 fdiv.s ft0, ft8, fa5");
COMPARE(fsqrt_s(ft0, ft8), "580e0053 fsqrt.s ft0, ft8");
COMPARE(fsgnj_s(ft0, ft8, fa5), "20fe0053 fsgnj.s ft0, ft8, fa5");
COMPARE(fsgnjn_s(ft0, ft8, fa5), "20fe1053 fsgnjn.s ft0, ft8, fa5");
COMPARE(fsgnjx_s(ft0, ft8, fa5), "20fe2053 fsgnjx.s ft0, ft8, fa5");
COMPARE(fmin_s(ft0, ft8, fa5), "28fe0053 fmin.s ft0, ft8, fa5");
COMPARE(fmax_s(ft0, ft8, fa5), "28fe1053 fmax.s ft0, ft8, fa5");
COMPARE(fcvt_w_s(a0, ft8, RNE), "c00e0553 fcvt.w.s [RNE] a0, ft8");
COMPARE(fcvt_wu_s(a0, ft8, RTZ), "c01e1553 fcvt.wu.s [RTZ] a0, ft8");
COMPARE(fmv_x_w(a0, ft8), "e00e0553 fmv.x.w a0, ft8");
COMPARE(feq_s(a0, ft8, fa5), "a0fe2553 feq.s a0, ft8, fa5");
COMPARE(flt_s(a0, ft8, fa5), "a0fe1553 flt.s a0, ft8, fa5");
COMPARE(fle_s(a0, ft8, fa5), "a0fe0553 fle.s a0, ft8, fa5");
COMPARE(fclass_s(a0, ft8), "e00e1553 fclass.s a0, ft8");
COMPARE(fcvt_s_w(ft0, s3), "d0098053 fcvt.s.w ft0, s3");
COMPARE(fcvt_s_wu(ft0, s3), "d0198053 fcvt.s.wu ft0, s3");
COMPARE(fmv_w_x(ft0, s3), "f0098053 fmv.w.x ft0, s3");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64F) {
SET_UP();
// RV64F Standard Extension (in addition to RV32F)
COMPARE(fcvt_l_s(a0, ft8, RNE), "c02e0553 fcvt.l.s [RNE] a0, ft8");
COMPARE(fcvt_lu_s(a0, ft8, RMM), "c03e4553 fcvt.lu.s [RMM] a0, ft8");
COMPARE(fcvt_s_l(ft0, s3), "d0298053 fcvt.s.l ft0, s3");
COMPARE(fcvt_s_lu(ft0, s3), "d0398053 fcvt.s.lu ft0, s3");
VERIFY_RUN();
}
#endif
TEST_F(DisasmRiscvTest, RV32D) {
SET_UP();
// RV32D Standard Extension
COMPARE(fld(ft0, s3, -268), "ef49b007 fld ft0, -268(s3)");
COMPARE(fsd(ft7, sp, -268), "ee713a27 fsd ft7, -268(sp)");
COMPARE(fmadd_d(ft0, ft8, fa5, fs5),
"aafe0043 fmadd.d ft0, ft8, fa5, fs5");
COMPARE(fmsub_d(ft0, ft8, fa5, fs1),
"4afe0047 fmsub.d ft0, ft8, fa5, fs1");
COMPARE(fnmsub_d(ft0, ft8, fa5, fs2),
"92fe004b fnmsub.d ft0, ft8, fa5, fs2");
COMPARE(fnmadd_d(ft0, ft8, fa5, fs3),
"9afe004f fnmadd.d ft0, ft8, fa5, fs3");
COMPARE(fadd_d(ft0, ft8, fa5), "02fe0053 fadd.d ft0, ft8, fa5");
COMPARE(fsub_d(ft0, ft8, fa5), "0afe0053 fsub.d ft0, ft8, fa5");
COMPARE(fmul_d(ft0, ft8, fa5), "12fe0053 fmul.d ft0, ft8, fa5");
COMPARE(fdiv_d(ft0, ft8, fa5), "1afe0053 fdiv.d ft0, ft8, fa5");
COMPARE(fsqrt_d(ft0, ft8), "5a0e0053 fsqrt.d ft0, ft8");
COMPARE(fsgnj_d(ft0, ft8, fa5), "22fe0053 fsgnj.d ft0, ft8, fa5");
COMPARE(fsgnjn_d(ft0, ft8, fa5), "22fe1053 fsgnjn.d ft0, ft8, fa5");
COMPARE(fsgnjx_d(ft0, ft8, fa5), "22fe2053 fsgnjx.d ft0, ft8, fa5");
COMPARE(fmin_d(ft0, ft8, fa5), "2afe0053 fmin.d ft0, ft8, fa5");
COMPARE(fmax_d(ft0, ft8, fa5), "2afe1053 fmax.d ft0, ft8, fa5");
COMPARE(fcvt_s_d(ft0, ft8, RDN), "401e2053 fcvt.s.d [RDN] ft0, ft8");
COMPARE(fcvt_d_s(ft0, fa0), "42050053 fcvt.d.s ft0, fa0");
COMPARE(feq_d(a0, ft8, fa5), "a2fe2553 feq.d a0, ft8, fa5");
COMPARE(flt_d(a0, ft8, fa5), "a2fe1553 flt.d a0, ft8, fa5");
COMPARE(fle_d(a0, ft8, fa5), "a2fe0553 fle.d a0, ft8, fa5");
COMPARE(fclass_d(a0, ft8), "e20e1553 fclass.d a0, ft8");
COMPARE(fcvt_w_d(a0, ft8, RNE), "c20e0553 fcvt.w.d [RNE] a0, ft8");
COMPARE(fcvt_wu_d(a0, ft8, RUP), "c21e3553 fcvt.wu.d [RUP] a0, ft8");
COMPARE(fcvt_d_w(ft0, s3), "d2098053 fcvt.d.w ft0, s3");
COMPARE(fcvt_d_wu(ft0, s3), "d2198053 fcvt.d.wu ft0, s3");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64D) {
SET_UP();
// RV64D Standard Extension (in addition to RV32D)
COMPARE(fcvt_l_d(a0, ft8, RMM), "c22e4553 fcvt.l.d [RMM] a0, ft8");
COMPARE(fcvt_lu_d(a0, ft8, RDN), "c23e2553 fcvt.lu.d [RDN] a0, ft8");
COMPARE(fmv_x_d(a0, ft8), "e20e0553 fmv.x.d a0, ft8");
COMPARE(fcvt_d_l(ft0, s3), "d2298053 fcvt.d.l ft0, s3");
COMPARE(fcvt_d_lu(ft0, s3), "d2398053 fcvt.d.lu ft0, s3");
COMPARE(fmv_d_x(ft0, s3), "f2098053 fmv.d.x ft0, s3");
VERIFY_RUN();
}
#endif
TEST_F(DisasmRiscvTest, PSEUDO) {
SET_UP();
// pseodu instructions according to rISCV assembly programmer's handbook
COMPARE(nop(), "00000013 nop");
COMPARE(RV_li(t6, -12), "ff400f93 li t6, -12");
COMPARE(mv(t0, a4), "00070293 mv t0, a4");
COMPARE(not_(t0, a5), "fff7c293 not t0, a5");
COMPARE(neg(ra, a6), "410000b3 neg ra, a6");
#ifdef V8_TARGET_ARCH_RISCV64
COMPARE(negw(t2, fp), "408003bb negw t2, fp");
COMPARE(sext_w(t0, s1), "0004829b sext.w t0, s1");
#endif
COMPARE(seqz(sp, s2), "00193113 seqz sp, s2");
COMPARE(snez(fp, s3), "01303433 snez fp, s3");
COMPARE(sltz(a0, t5), "000f2533 sltz a0, t5");
COMPARE(sgtz(a1, t4), "01d025b3 sgtz a1, t4");
COMPARE(fmv_s(fa0, fs4), "214a0553 fmv.s fa0, fs4");
COMPARE(fabs_s(fa1, fs3), "2139a5d3 fabs.s fa1, fs3");
COMPARE(fneg_s(fa2, fs5), "215a9653 fneg.s fa2, fs5");
COMPARE(fmv_d(fa3, fs2), "232906d3 fmv.d fa3, fs2");
COMPARE(fabs_d(fs0, fs2), "23292453 fabs.d fs0, fs2");
COMPARE(fneg_d(fs1, fs1), "229494d3 fneg.d fs1, fs1");
COMPARE_PC_REL(j(-1024), "c01ff06f j -1024", -1024);
COMPARE_PC_REL(jal(32), "020000ef jal 32", 32);
COMPARE(jr(a1), "00058067 jr a1");
COMPARE(jalr(a1), "000580e7 jalr a1");
COMPARE(ret(), "00008067 ret");
// COMPARE(call(int32_t offset);
COMPARE(rdinstret(t0), "c02022f3 rdinstret t0");
COMPARE(rdinstreth(a0), "c8202573 rdinstreth a0");
COMPARE(rdcycle(a4), "c0002773 rdcycle a4");
COMPARE(rdcycleh(a5), "c80027f3 rdcycleh a5");
COMPARE(rdtime(a3), "c01026f3 rdtime a3");
COMPARE(rdtimeh(t2), "c81023f3 rdtimeh t2");
COMPARE(csrr(t3, csr_cycle), "c0002e73 rdcycle t3");
COMPARE(csrw(csr_instret, a1), "c0259073 csrw csr_instret, a1");
COMPARE(csrs(csr_timeh, a2), "c8162073 csrs csr_timeh, a2");
COMPARE(csrc(csr_cycleh, t1), "c8033073 csrc csr_cycleh, t1");
COMPARE(csrwi(csr_time, 0xf), "c017d073 csrwi csr_time, 0xf");
COMPARE(csrsi(csr_cycleh, 0x1), "c800e073 csrsi csr_cycleh, 0x1");
COMPARE(csrci(csr_instreth, 0x15),
"c82af073 csrci csr_instreth, 0x15");
COMPARE(frcsr(t4), "00302ef3 frcsr t4");
COMPARE(fscsr(t1, a1), "00359373 fscsr t1, a1");
COMPARE(fscsr(a4), "00371073 fscsr a4");
COMPARE(frrm(t2), "002023f3 frrm t2");
COMPARE(fsrm(t0, a1), "002592f3 fsrm t0, a1");
COMPARE(fsrm(a5), "00279073 fsrm a5");
COMPARE(frflags(s5), "00102af3 frflags s5");
COMPARE(fsflags(s2, t1), "00131973 fsflags s2, t1");
COMPARE(fsflags(s1), "00149073 fsflags s1");
VERIFY_RUN();
}
#ifdef V8_TARGET_ARCH_RISCV64
TEST_F(DisasmRiscvTest, RV64C) {
i::v8_flags.riscv_c_extension = true;
SET_UP();
COMPARE(c_nop(), "00000001 nop");
COMPARE(c_addi(s3, -25), "0000199d addi s3, s3, -25");
COMPARE(c_addiw(gp, -30), "00003189 addiw gp, gp, -30");
COMPARE(c_addi16sp(-432), "00007161 addi sp, sp, -432");
COMPARE(c_addi4spn(a1, 924), "00000f6c addi a1, sp, 924");
COMPARE(c_li(t6, -15), "00005fc5 li t6, -15");
COMPARE(c_lui(s1, 0xf4), "000074d1 lui s1, 0xffff4");
COMPARE(c_slli(s9, 60), "00001cf2 slli s9, s9, 60");
COMPARE(c_fldsp(fa1, 360), "000035b6 fld fa1, 360(sp)");
COMPARE(c_lwsp(s7, 244), "00005bde lw s7, 244(sp)");
COMPARE(c_ldsp(s6, 344), "00006b76 ld s6, 344(sp)");
COMPARE(c_jr(a1), "00008582 jr a1");
COMPARE(c_mv(t0, a4), "000082ba mv t0, a4");
COMPARE(c_ebreak(), "00009002 ebreak");
COMPARE(c_jalr(a1), "00009582 jalr a1");
COMPARE(c_add(s6, t0), "00009b16 add s6, s6, t0");
COMPARE(c_sub(s1, a0), "00008c89 sub s1, s1, a0");
COMPARE(c_xor(s1, a0), "00008ca9 xor s1, s1, a0");
COMPARE(c_or(s1, a0), "00008cc9 or s1, s1, a0");
COMPARE(c_and(s1, a0), "00008ce9 and s1, s1, a0");
COMPARE(c_subw(s1, a0), "00009c89 subw s1, s1, a0");
COMPARE(c_addw(a0, a1), "00009d2d addw a0, a0, a1");
COMPARE(c_fsdsp(fa4, 232), "0000b5ba fsd fa4, 232(sp)");
COMPARE(c_swsp(s6, 180), "0000db5a sw s6, 180(sp)");
COMPARE(c_sdsp(a4, 216), "0000edba sd a4, 216(sp)");
COMPARE(c_lw(a2, s1, 24), "00004c90 lw a2, 24(s1)");
COMPARE(c_ld(a2, s1, 24), "00006c90 ld a2, 24(s1)");
COMPARE(c_fld(fa1, s1, 24), "00002c8c fld fa1, 24(s1)");
COMPARE(c_sw(a2, s1, 24), "0000cc90 sw a2, 24(s1)");
COMPARE(c_sd(a2, s1, 24), "0000ec90 sd a2, 24(s1)");
COMPARE(c_fsd(fa1, s1, 24), "0000ac8c fsd fa1, 24(s1)");
COMPARE(c_j(-12), "0000bfd5 j -12");
COMPARE(c_beqz(a0, -12), "0000d975 beqz a0, x0, -12");
COMPARE(c_bnez(a0, -12), "0000f975 bnez a0, x0, -12");
COMPARE(c_srli(a1, 24), "000081e1 srli a1, a1, 24");
COMPARE(c_andi(a1, 24), "000089e1 andi a1, a1, 24");
COMPARE(c_srai(a1, 24), "000085e1 srai a1, a1, 24");
VERIFY_RUN();
}
#endif
/*
TEST_F(DisasmRiscvTest, Previleged) {
SET_UP();
// Privileged
COMPARE(uret(), "");
COMPARE(sret(), "");
COMPARE(mret(), "");
COMPARE(wfi(), "");
COMPARE(sfence_vma(s3, s4), "");
VERIFY_RUN();
}
*/
TEST_F(DisasmRiscvTest, RVV) {
if (!CpuFeatures::IsSupported(RISCV_SIMD)) return;
SET_UP();
COMPARE(VU.set(kScratchReg, E64, m1),
"018079d7 vsetvli s3, zero_reg, E64, m1");
COMPARE(vl(v2, a0, 0, VSew::E8), "02050107 vle8.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E16), "02055107 vle16.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E32), "02056107 vle32.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E64), "02057107 vle64.v v2, (a0)");
COMPARE(vadd_vv(v0, v0, v1), "02008057 vadd.vv v0, v0, v1");
COMPARE(vadd_vx(v0, v1, t0), "0212c057 vadd.vx v0, v1, t0");
COMPARE(vadd_vi(v0, v1, 3), "0211b057 vadd.vi v0, v1, 3");
COMPARE(vsub_vv(v2, v3, v4), "0a320157 vsub.vv v2, v3, v4");
COMPARE(vsub_vx(v2, v3, a4), "0a374157 vsub.vx v2, v3, a4");
COMPARE(vsadd_vv(v0, v0, v1), "86008057 vsadd.vv v0, v0, v1");
COMPARE(vsadd_vx(v4, v5, t1), "86534257 vsadd.vx v4, v5, t1");
COMPARE(vsadd_vi(v6, v7, 5), "8672b357 vsadd.vi v6, v7, 5");
COMPARE(vssub_vv(v2, v3, v4), "8e320157 vssub.vv v2, v3, v4");
COMPARE(vssub_vx(v2, v3, t4), "8e3ec157 vssub.vx v2, v3, t4");
COMPARE(vor_vv(v21, v31, v9), "2bf48ad7 vor.vv v21, v31, v9");
COMPARE(vor_vx(v19, v29, s7), "2bdbc9d7 vor.vx v19, v29, s7");
COMPARE(vor_vi(v17, v28, 7), "2bc3b8d7 vor.vi v17, v28, 7");
COMPARE(vxor_vv(v21, v31, v9), "2ff48ad7 vxor.vv v21, v31, v9");
COMPARE(vxor_vx(v19, v29, s7), "2fdbc9d7 vxor.vx v19, v29, s7");
COMPARE(vxor_vi(v17, v28, 7), "2fc3b8d7 vxor.vi v17, v28, 7");
COMPARE(vand_vv(v21, v31, v9), "27f48ad7 vand.vv v21, v31, v9");
COMPARE(vand_vx(v19, v29, s7), "27dbc9d7 vand.vx v19, v29, s7");
COMPARE(vand_vi(v17, v28, 7), "27c3b8d7 vand.vi v17, v28, 7");
COMPARE(vmseq_vv(v17, v28, v29), "63ce88d7 vmseq.vv v17, v28, v29");
COMPARE(vmsne_vv(v17, v28, v29), "67ce88d7 vmsne.vv v17, v28, v29");
COMPARE(vmseq_vx(v17, v28, t2), "63c3c8d7 vmseq.vx v17, v28, t2");
COMPARE(vmsne_vx(v17, v28, t6), "67cfc8d7 vmsne.vx v17, v28, t6");
COMPARE(vmseq_vi(v17, v28, 7), "63c3b8d7 vmseq.vi v17, v28, 7");
COMPARE(vmsne_vi(v17, v28, 7), "67c3b8d7 vmsne.vi v17, v28, 7");
COMPARE(vmsltu_vv(v17, v28, v14), "6bc708d7 vmsltu.vv v17, v28, v14");
COMPARE(vmsltu_vx(v17, v28, a5), "6bc7c8d7 vmsltu.vx v17, v28, a5");
COMPARE(vmslt_vv(v17, v28, v14), "6fc708d7 vmslt.vv v17, v28, v14");
COMPARE(vmslt_vx(v17, v28, a5), "6fc7c8d7 vmslt.vx v17, v28, a5");
COMPARE(vmsleu_vv(v17, v28, v14), "73c708d7 vmsleu.vv v17, v28, v14");
COMPARE(vmsleu_vx(v17, v28, a5), "73c7c8d7 vmsleu.vx v17, v28, a5");
COMPARE(vmsleu_vi(v17, v28, 5), "73c2b8d7 vmsleu.vi v17, v28, 5");
COMPARE(vmsle_vv(v17, v28, v14), "77c708d7 vmsle.vv v17, v28, v14");
COMPARE(vmsle_vx(v17, v28, a5), "77c7c8d7 vmsle.vx v17, v28, a5");
COMPARE(vmsle_vi(v17, v28, 5), "77c2b8d7 vmsle.vi v17, v28, 5");
COMPARE(vmsgt_vx(v17, v28, a5), "7fc7c8d7 vmsgt.vx v17, v28, a5");
COMPARE(vmsgt_vi(v17, v28, 5), "7fc2b8d7 vmsgt.vi v17, v28, 5");
COMPARE(vmsgtu_vx(v17, v28, a5), "7bc7c8d7 vmsgtu.vx v17, v28, a5");
COMPARE(vmsgtu_vi(v17, v28, 5), "7bc2b8d7 vmsgtu.vi v17, v28, 5");
COMPARE(vadc_vv(v7, v9, v6), "406483d7 vadc.vvm v7, v6, v9");
COMPARE(vadc_vx(v7, t6, v9), "409fc3d7 vadc.vxm v7, v9, t6");
COMPARE(vadc_vi(v7, 5, v9), "4092b3d7 vadc.vim v7, v9, 5");
COMPARE(vfadd_vv(v17, v14, v28), "02ee18d7 vfadd.vv v17, v14, v28");
COMPARE(vfsub_vv(v17, v14, v28), "0aee18d7 vfsub.vv v17, v14, v28");
COMPARE(vfmul_vv(v17, v14, v28), "92ee18d7 vfmul.vv v17, v14, v28");
COMPARE(vfdiv_vv(v17, v14, v28), "82ee18d7 vfdiv.vv v17, v14, v28");
COMPARE(vfmv_vf(v17, fa5), "5e07d8d7 vfmv.v.f v17, fa5");
COMPARE(vfmv_fs(fa5, v17), "431017d7 vfmv.f.s fa5, v17");
// Vector Single-Width Floating-Point Fused Multiply-Add Instructions
COMPARE(vfmadd_vv(v17, v14, v28), "a3c718d7 vfmadd.vv v17, v14, v28");
COMPARE(vfnmadd_vv(v17, v14, v28), "a7c718d7 vfnmadd.vv v17, v14, v28");
COMPARE(vfmsub_vv(v17, v14, v28), "abc718d7 vfmsub.vv v17, v14, v28");
COMPARE(vfnmsub_vv(v17, v14, v28), "afc718d7 vfnmsub.vv v17, v14, v28");
COMPARE(vfmacc_vv(v17, v14, v28), "b3c718d7 vfmacc.vv v17, v14, v28");
COMPARE(vfnmacc_vv(v17, v14, v28), "b7c718d7 vfnmacc.vv v17, v14, v28");
COMPARE(vfmsac_vv(v17, v14, v28), "bbc718d7 vfmsac.vv v17, v14, v28");
COMPARE(vfnmsac_vv(v17, v14, v28), "bfc718d7 vfnmsac.vv v17, v14, v28");
COMPARE(vfmadd_vf(v17, fa5, v28), "a3c7d8d7 vfmadd.vf v17, fa5, v28");
COMPARE(vfnmadd_vf(v17, fa5, v28), "a7c7d8d7 vfnmadd.vf v17, fa5, v28");
COMPARE(vfmsub_vf(v17, fa5, v28), "abc7d8d7 vfmsub.vf v17, fa5, v28");
COMPARE(vfnmsub_vf(v17, fa5, v28), "afc7d8d7 vfnmsub.vf v17, fa5, v28");
COMPARE(vfmacc_vf(v17, fa5, v28), "b3c7d8d7 vfmacc.vf v17, fa5, v28");
COMPARE(vfnmacc_vf(v17, fa5, v28), "b7c7d8d7 vfnmacc.vf v17, fa5, v28");
COMPARE(vfmsac_vf(v17, fa5, v28), "bbc7d8d7 vfmsac.vf v17, fa5, v28");
COMPARE(vfnmsac_vf(v17, fa5, v28), "bfc7d8d7 vfnmsac.vf v17, fa5, v28");
// Vector Narrowing Fixed-Point Clip Instructions
COMPARE(vnclip_vi(v17, v14, 5), "bee2b8d7 vnclip.wi v17, v14, 5");
COMPARE(vnclip_vx(v17, v14, a5), "bee7c8d7 vnclip.wx v17, v14, a5");
COMPARE(vnclip_vv(v17, v14, v28), "beee08d7 vnclip.wv v17, v14, v28");
COMPARE(vnclipu_vi(v17, v14, 5), "bae2b8d7 vnclipu.wi v17, v14, 5");
COMPARE(vnclipu_vx(v17, v14, a5), "bae7c8d7 vnclipu.wx v17, v14, a5");
COMPARE(vnclipu_vv(v17, v14, v28), "baee08d7 vnclipu.wv v17, v14, v28");
// Vector Integer Extension
COMPARE(vzext_vf8(v17, v14), "4ae128d7 vzext.vf8 v17, v14");
COMPARE(vsext_vf8(v17, v14), "4ae1a8d7 vsext.vf8 v17, v14");
COMPARE(vzext_vf4(v17, v14), "4ae228d7 vzext.vf4 v17, v14");
COMPARE(vsext_vf4(v17, v14), "4ae2a8d7 vsext.vf4 v17, v14");
COMPARE(vzext_vf2(v17, v14), "4ae328d7 vzext.vf2 v17, v14");
COMPARE(vsext_vf2(v17, v14), "4ae3a8d7 vsext.vf2 v17, v14");
// Vector Mask Instructions
COMPARE(vfirst_m(a5, v17), "4318a7d7 vfirst.m a5, v17");
COMPARE(vcpop_m(a5, v17), "431827d7 vcpop.m a5, v17");
COMPARE(vfsqrt_v(v17, v28), "4fc018d7 vfsqrt.v v17, v28")
COMPARE(vfrsqrt7_v(v17, v28), "4fc218d7 vfrsqrt7.v v17, v28")
COMPARE(vfrec7_v(v17, v28), "4fc298d7 vfrec7.v v17, v28")
COMPARE(vfclass_v(v17, v28), "4fc818d7 vfclass.v v17, v28")
// Vector Widening Floating-Point Add/Subtract Instructions
COMPARE(vfwadd_vv(v17, v14, v28), "c2ee18d7 vfwadd.vv v17, v14, v28");
COMPARE(vfwsub_vv(v17, v14, v28), "caee18d7 vfwsub.vv v17, v14, v28");
COMPARE(vfwadd_wv(v17, v14, v28), "d2ee18d7 vfwadd.wv v17, v14, v28");
COMPARE(vfwsub_wv(v17, v14, v28), "daee18d7 vfwsub.wv v17, v14, v28");
COMPARE(vfwadd_vf(v17, v28, fa5), "c3c7d8d7 vfwadd.vf v17, v28, fa5");
COMPARE(vfwsub_vf(v17, v28, fa5), "cbc7d8d7 vfwsub.vf v17, v28, fa5");
COMPARE(vfwadd_wf(v17, v28, fa5), "d3c7d8d7 vfwadd.wf v17, v28, fa5");
COMPARE(vfwsub_wf(v17, v28, fa5), "dbc7d8d7 vfwsub.wf v17, v28, fa5");
// Vector Widening Floating-Point Reduction Instructions
COMPARE(vfwredusum_vs(v17, v14, v28),
"c6ee18d7 vfwredusum.vs v17, v14, v28");
COMPARE(vfwredosum_vs(v17, v14, v28),
"ceee18d7 vfwredosum.vs v17, v14, v28");
// Vector Widening Floating-Point Multiply
COMPARE(vfwmul_vv(v17, v14, v28), "e2ee18d7 vfwmul.vv v17, v14, v28");
COMPARE(vfwmul_vf(v17, v28, fa5), "e3c7d8d7 vfwmul.vf v17, v28, fa5");
// Vector Widening Floating-Point Fused Multiply-Add Instructions
COMPARE(vfwmacc_vv(v17, v14, v28), "f3c718d7 vfwmacc.vv v17, v14, v28");
COMPARE(vfwnmacc_vv(v17, v14, v28),
"f7c718d7 vfwnmacc.vv v17, v14, v28");
COMPARE(vfwmsac_vv(v17, v14, v28), "fbc718d7 vfwmsac.vv v17, v14, v28");
COMPARE(vfwnmsac_vv(v17, v14, v28),
"ffc718d7 vfwnmsac.vv v17, v14, v28");
COMPARE(vfwmacc_vf(v17, fa5, v28), "f3c7d8d7 vfwmacc.vf v17, fa5, v28");
COMPARE(vfwnmacc_vf(v17, fa5, v28),
"f7c7d8d7 vfwnmacc.vf v17, fa5, v28");
COMPARE(vfwmsac_vf(v17, fa5, v28), "fbc7d8d7 vfwmsac.vf v17, fa5, v28");
COMPARE(vfwnmsac_vf(v17, fa5, v28),
"ffc7d8d7 vfwnmsac.vf v17, fa5, v28");
VERIFY_RUN();
}
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,232 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include <stdlib.h>
#include "src/codegen/macro-assembler.h"
#include "src/debug/debug.h"
#include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h"
#include "src/execution/frames-inl.h"
#include "src/init/v8.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using DisasmS390Test = TestWithIsolate;
bool DisassembleAndCompare(uint8_t* pc, const char* compare_string) {
disasm::NameConverter converter;
disasm::Disassembler disasm(converter);
base::EmbeddedVector<char, 128> disasm_buffer;
disasm.InstructionDecode(disasm_buffer, pc);
if (strcmp(compare_string, disasm_buffer.begin()) != 0) {
fprintf(stderr,
"expected: \n"
"%s\n"
"disassembled: \n"
"%s\n\n",
compare_string, disasm_buffer.begin());
return false;
}
return true;
}
// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
#define SET_UP() \
HandleScope scope(isolate()); \
uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(4 * 1024)); \
Assembler assm(AssemblerOptions{}, \
ExternalAssemblerBuffer(buffer, 4 * 1024)); \
bool failure = false;
// This macro assembles one instruction using the preallocated assembler and
// disassembles the generated instruction, comparing the output to the expected
// value. If the comparison fails an error message is printed, but the test
// continues to run until the end.
#define COMPARE(asm_, compare_string) \
{ \
int pc_offset = assm.pc_offset(); \
uint8_t* progcounter = &buffer[pc_offset]; \
assm.asm_; \
if (!DisassembleAndCompare(progcounter, compare_string)) failure = true; \
}
// Force emission of any pending literals into a pool.
#define EMIT_PENDING_LITERALS() assm.CheckConstPool(true, false)
// Verify that all invocations of the COMPARE macro passed successfully.
// Exit with a failure if at least one of the tests failed.
#define VERIFY_RUN() \
if (failure) { \
FATAL("S390 Disassembler tests failed.\n"); \
}
TEST_F(DisasmS390Test, TwoBytes) {
SET_UP();
COMPARE(ar(r3, r10), "1a3a ar\tr3,r10");
COMPARE(sr(r8, ip), "1b8c sr\tr8,ip");
COMPARE(mr_z(r0, r6), "1c06 mr\tr0,r6");
COMPARE(dr(r0, r5), "1d05 dr\tr0,r5");
COMPARE(or_z(r4, r2), "1642 or\tr4,r2");
COMPARE(nr(fp, r9), "14b9 nr\tfp,r9");
COMPARE(xr(r10, ip), "17ac xr\tr10,ip");
COMPARE(lr(r2, r13), "182d lr\tr2,r13");
COMPARE(cr_z(r9, r3), "1993 cr\tr9,r3");
COMPARE(clr(sp, r4), "15f4 clr\tsp,r4");
COMPARE(bcr(eq, r8), "0788 bcr\t0x8,r8");
COMPARE(ltr(r10, r1), "12a1 ltr\tr10,r1");
COMPARE(alr(r6, r8), "1e68 alr\tr6,r8");
COMPARE(slr(r3, ip), "1f3c slr\tr3,ip");
COMPARE(lnr(r4, r1), "1141 lnr\tr4,r1");
COMPARE(lcr(r0, r3), "1303 lcr\tr0,r3");
COMPARE(basr(r14, r7), "0de7 basr\tr14,r7");
COMPARE(ldr(d4, d6), "2846 ldr\td4,d6");
VERIFY_RUN();
}
TEST_F(DisasmS390Test, FourBytes) {
SET_UP();
COMPARE(aghi(r5, Operand(1)), "a75b0001 aghi\tr5,1");
COMPARE(lghi(r6, Operand(8)), "a7690008 lghi\tr6,8");
COMPARE(mghi(r1, Operand(2)), "a71d0002 mghi\tr1,2");
COMPARE(cghi(r3, Operand(7)), "a73f0007 cghi\tr3,7");
COMPARE(iihh(r10, Operand(8)), "a5a00008 iihh\tr10,8");
COMPARE(iihl(r9, Operand(10)), "a591000a iihl\tr9,10");
COMPARE(iilh(r0, Operand(40)), "a5020028 iilh\tr0,40");
COMPARE(iill(r6, Operand(19)), "a5630013 iill\tr6,19");
COMPARE(oill(r9, Operand(9)), "a59b0009 oill\tr9,9");
COMPARE(tmll(r4, Operand(7)), "a7410007 tmll\tr4,7");
COMPARE(stm(r2, r5, MemOperand(r9, 44)), "9025902c stm\tr2,r5,44(r9)");
COMPARE(lm(r8, r0, MemOperand(sp, 88)), "9880f058 lm\tr8,r0,88(sp)");
COMPARE(nill(r7, Operand(30)), "a577001e nill\tr7,30");
COMPARE(nilh(r8, Operand(4)), "a5860004 nilh\tr8,4");
COMPARE(ah(r9, MemOperand(r5, r4, 4)), "4a954004 ah\tr9,4(r5,r4)");
COMPARE(sh(r8, MemOperand(r1, r2, 6)), "4b812006 sh\tr8,6(r1,r2)");
COMPARE(mh(r5, MemOperand(r9, r8, 7)), "4c598007 mh\tr5,7(r9,r8)");
VERIFY_RUN();
}
TEST_F(DisasmS390Test, SixBytes) {
SET_UP();
COMPARE(llihf(ip, Operand(90000)), "c0ce00015f90 llihf\tip,90000");
COMPARE(agsi(MemOperand(r9, 1000), Operand(70)),
"eb4693e8007a agsi\t1000(r9),70");
COMPARE(clgfi(r7, Operand(80)), "c27e00000050 clgfi\tr7,80");
COMPARE(cgfi(r8, Operand(10)), "c28c0000000a cgfi\tr8,10");
COMPARE(xihf(fp, Operand(8)), "c0b600000008 xihf\tfp,8");
COMPARE(sllg(r0, r1, r2), "eb012000000d sllg\tr0,r1,0(r2)");
COMPARE(sllg(r0, r1, Operand(10)), "eb01000a000d sllg\tr0,r1,10(r0)");
COMPARE(srlg(r1, r3, Operand(10)), "eb13000a000c srlg\tr1,r3,10(r0)");
COMPARE(srlg(r1, r3, r10), "eb13a000000c srlg\tr1,r3,0(r10)");
COMPARE(slag(r1, r3, Operand(2)), "eb130002000b slag\tr1,r3,2(r0)");
COMPARE(slag(r1, r3, r2), "eb132000000b slag\tr1,r3,0(r2)");
COMPARE(srag(r1, r3, r2), "eb132000000a srag\tr1,r3,0(r2)");
COMPARE(srag(r1, r3, Operand(2)), "eb130002000a srag\tr1,r3,2(r0)");
COMPARE(risbg(r1, r2, Operand(3), Operand(5), Operand(2)),
"ec1203050255 risbg\tr1,r2,3,5,2");
COMPARE(risbgn(r1, r2, Operand(3), Operand(5), Operand(2)),
"ec1203050259 risbgn\tr1,r2,3,5,2");
COMPARE(stmg(r3, r4, MemOperand(sp, 10)),
"eb34f00a0024 stmg\tr3,r4,10(sp)");
COMPARE(ltg(r1, MemOperand(r4, sp, 10)), "e314f00a0002 ltg\tr1,10(r4,sp)");
COMPARE(lgh(r8, MemOperand(r1, 8888)), "e38012b80215 lgh\tr8,8888(r1)");
COMPARE(ag(r4, MemOperand(r9, r4, 2046)),
"e34947fe0008 ag\tr4,2046(r9,r4)");
COMPARE(agf(r1, MemOperand(r3, sp, 9)), "e313f0090018 agf\tr1,9(r3,sp)");
COMPARE(sg(r9, MemOperand(r5, 15)), "e390500f0009 sg\tr9,15(r5)");
COMPARE(ng(r7, MemOperand(r5, r6, 1000)),
"e37563e80080 ng\tr7,1000(r5,r6)");
COMPARE(og(r2, MemOperand(r8, r0, 1000)),
"e32803e80081 og\tr2,1000(r8,r0)");
COMPARE(xg(r9, MemOperand(r3, 8888)), "e39032b80282 xg\tr9,8888(r3)");
COMPARE(ng(r0, MemOperand(r9, r3, 900)), "e30933840080 ng\tr0,900(r9,r3)");
COMPARE(og(r3, MemOperand(r8, r2, 8888)),
"e33822b80281 og\tr3,8888(r8,r2)");
COMPARE(xg(r9, MemOperand(r3, 15)), "e390300f0082 xg\tr9,15(r3)");
COMPARE(cg(r0, MemOperand(r5, r4, 4)), "e30540040020 cg\tr0,4(r5,r4)");
COMPARE(lg(r1, MemOperand(r7, r8, 90)), "e317805a0004 lg\tr1,90(r7,r8)");
COMPARE(lgf(r1, MemOperand(sp, 15)), "e310f00f0014 lgf\tr1,15(sp)");
COMPARE(llgf(r0, MemOperand(r3, r4, 8)), "e30340080016 llgf\tr0,8(r3,r4)");
COMPARE(alg(r8, MemOperand(r4, 11)), "e380400b000a alg\tr8,11(r4)");
COMPARE(slg(r1, MemOperand(r5, r6, 11)), "e315600b000b slg\tr1,11(r5,r6)");
COMPARE(sgf(r0, MemOperand(r4, r5, 8888)),
"e30452b80219 sgf\tr0,8888(r4,r5)");
COMPARE(llgh(r4, MemOperand(r1, 8000)), "e3401f400191 llgh\tr4,8000(r1)");
COMPARE(llgc(r0, MemOperand(r4, r5, 30)),
"e304501e0090 llgc\tr0,30(r4,r5)");
COMPARE(lgb(r9, MemOperand(r8, r7, 10)), "e398700a0077 lgb\tr9,10(r8,r7)");
COMPARE(stg(r0, MemOperand(r9, 10)), "e300900a0024 stg\tr0,10(r9)");
COMPARE(mvghi(MemOperand(r7, 25), Operand(100)),
"e54870190064 mvghi\t25(r7),100");
COMPARE(algfi(r1, Operand(34250)), "c21a000085ca algfi\tr1,34250");
COMPARE(slgfi(r1, Operand(87654321)), "c21405397fb1 slgfi\tr1,87654321");
COMPARE(nihf(r2, Operand(8888)), "c02a000022b8 nihf\tr2,8888");
COMPARE(oihf(r6, Operand(9000)), "c06c00002328 oihf\tr6,9000");
COMPARE(msgfi(r6, Operand(90000)), "c26000015f90 msgfi\tr6,90000");
COMPARE(iihf(r6, Operand(9)), "c06800000009 iihf\tr6,9");
COMPARE(srlk(r1, r3, r2), "eb13200000de srlk\tr1,r3,0(r2)");
COMPARE(srlk(r1, r3, Operand(2)), "eb13000200de srlk\tr1,r3,2(r0)");
COMPARE(lmy(r9, r10, MemOperand(r8, 100)),
"eb9a80640098 lmy\tr9,r10,100(r8)");
COMPARE(lmg(r7, r8, MemOperand(r9, 100)),
"eb7890640004 lmg\tr7,r8,100(r9)");
COMPARE(lay(fp, MemOperand(sp, 8000)), "e3b0ff400171 lay\tfp,8000(sp)");
COMPARE(cliy(MemOperand(sp, 80), Operand(80)),
"eb50f0500055 cliy\t80(sp),80");
COMPARE(tmy(MemOperand(r0, 20), Operand(10)),
"eb0a00140051 tmy\t20(r0),10");
COMPARE(clg(r9, MemOperand(r6, r7, 19)), "e39670130021 clg\tr9,19(r6,r7)");
COMPARE(bctg(r8, MemOperand(sp, 10)), "e380f00a0046 bctg\tr8,10(sp)");
COMPARE(icy(r2, MemOperand(r3, 2)), "e32030020073 icy\tr2,2(r3)");
COMPARE(mvc(MemOperand(r9, 9), MemOperand(r3, 15), Operand(10)),
"d20a9009300f mvc\t9(10,r9),15(r3)");
COMPARE(nilf(r0, Operand(8000)), "c00b00001f40 nilf\tr0,8000");
COMPARE(oilf(r9, Operand(1000)), "c09d000003e8 oilf\tr9,1000");
VERIFY_RUN();
}
#undef SET_UP
#undef COMPARE
#undef EMIT_PENDING_LITERALS
#undef VERIFY_RUN
} // namespace internal
} // namespace v8

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,194 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/arm/assembler-arm-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "src/utils/ostreams.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
const char* ErrorMessage(const char* msg) {
// If we are running on android and the output is not redirected (i.e. ends up
// in the android log) then we cannot find the error message in the output. This
// macro just returns the empty string in that case.
#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
return "";
#else
// We only print the abort reason if debug code is enabled. Otherwise we just
// stop execution. Return an empty string in that case.
return v8_flags.debug_code ? msg : "";
#endif
}
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, ErrorMessage("abort: no reason"));
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ Move32BitImmediate(r1, Operand(17));
__ cmp(r0, r1); // 1st parameter is in {r0}.
__ Check(ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, ErrorMessage("abort: no reason"));
}
struct MoveObjectAndSlotTestCase {
const char* comment;
Register dst_object;
Register dst_slot;
Register object;
Register offset_register = no_reg;
};
const MoveObjectAndSlotTestCase kMoveObjectAndSlotTestCases[] = {
{"no overlap", r0, r1, r2},
{"no overlap", r0, r1, r2, r3},
{"object == dst_object", r2, r1, r2},
{"object == dst_object", r2, r1, r2, r3},
{"object == dst_slot", r1, r2, r2},
{"object == dst_slot", r1, r2, r2, r3},
{"offset == dst_object", r0, r1, r2, r0},
{"offset == dst_object && object == dst_slot", r0, r1, r1, r0},
{"offset == dst_slot", r0, r1, r2, r1},
{"offset == dst_slot && object == dst_object", r0, r1, r0, r1}};
// Make sure we include offsets that cannot be encoded in an add instruction.
const int kOffsets[] = {0, 42, kMaxRegularHeapObjectSize, 0x101001};
template <typename T>
class MacroAssemblerTestWithParam : public MacroAssemblerTest,
public ::testing::WithParamInterface<T> {};
using MacroAssemblerTestMoveObjectAndSlot =
MacroAssemblerTestWithParam<MoveObjectAndSlotTestCase>;
TEST_P(MacroAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
const MoveObjectAndSlotTestCase test_case = GetParam();
TRACED_FOREACH(int32_t, offset, kOffsets) {
auto buffer = AllocateAssemblerBuffer();
constexpr Zone* no_zone = nullptr;
MacroAssembler masm(no_zone, AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ Push(r0);
__ Move(test_case.object, r1);
Register src_object = test_case.object;
Register dst_object = test_case.dst_object;
Register dst_slot = test_case.dst_slot;
Operand offset_operand(0);
if (test_case.offset_register == no_reg) {
offset_operand = Operand(offset);
} else {
__ mov(test_case.offset_register, Operand(offset));
offset_operand = Operand(test_case.offset_register);
}
std::stringstream comment;
comment << "-- " << test_case.comment << ": MoveObjectAndSlot("
<< dst_object << ", " << dst_slot << ", " << src_object << ", ";
if (test_case.offset_register == no_reg) {
comment << "#" << offset;
} else {
comment << test_case.offset_register;
}
comment << ") --";
__ RecordComment(comment.str().c_str());
__ MoveObjectAndSlot(dst_object, dst_slot, src_object, offset_operand);
__ RecordComment("--");
// The `result` pointer was saved on the stack.
UseScratchRegisterScope temps(&masm);
Register scratch = temps.Acquire();
__ Pop(scratch);
__ str(dst_object, MemOperand(scratch));
__ str(dst_slot, MemOperand(scratch, kSystemPointerSize));
__ Ret();
CodeDesc desc;
masm.GetCode(static_cast<LocalIsolate*>(nullptr), &desc);
if (v8_flags.print_code) {
Handle<Code> code =
Factory::CodeBuilder(isolate(), desc, CodeKind::FOR_TESTING).Build();
StdoutStream os;
Print(*code, os);
}
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, uint8_t**, uint8_t*>::FromBuffer(
isolate(), buffer->start());
uint8_t* object = new uint8_t[offset];
uint8_t* result[] = {nullptr, nullptr};
f.Call(result, object);
// The first element must be the address of the object, and the second the
// slot addressed by `offset`.
EXPECT_EQ(result[0], &object[0]);
EXPECT_EQ(result[1], &object[offset]);
delete[] object;
}
}
INSTANTIATE_TEST_SUITE_P(MacroAssemblerTest,
MacroAssemblerTestMoveObjectAndSlot,
::testing::ValuesIn(kMoveObjectAndSlotTestCases));
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,258 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/arm64/macro-assembler-arm64-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "src/utils/ostreams.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
const char* ErrorMessage(const char* msg) {
// If we are running on android and the output is not redirected (i.e. ends up
// in the android log) then we cannot find the error message in the output. This
// macro just returns the empty string in that case.
#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
return "";
#else
// We only print the abort reason if debug code is enabled. Otherwise we just
// stop execution. Return an empty string in that case.
return v8_flags.debug_code ? msg : "";
#endif
}
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
{
AssemblerBufferWriteScope rw_scope(*buffer);
__ CodeEntry();
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
}
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, ErrorMessage("abort: no reason"));
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
{
AssemblerBufferWriteScope rw_scope(*buffer);
__ CodeEntry();
// Fail if the first parameter is 17.
__ Mov(w1, Immediate(17));
__ Cmp(w0, w1); // 1st parameter is in {w0}.
__ Check(Condition::ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
}
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED({ f.Call(17); }, ErrorMessage("abort: no reason"));
}
TEST_F(MacroAssemblerTest, CompareAndBranch) {
const int kTestCases[] = {-42, 0, 42};
static_assert(Condition::eq == 0);
static_assert(Condition::le == 13);
TRACED_FORRANGE(int, cc, 0, 13) { // All conds except al and nv
Condition cond = static_cast<Condition>(cc);
TRACED_FOREACH(int, imm, kTestCases) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{},
CodeObjectRequired::kNo, buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
{
AssemblerBufferWriteScope rw_scope(*buffer);
__ CodeEntry();
Label start, lab;
__ Bind(&start);
__ CompareAndBranch(x0, Immediate(imm), cond, &lab);
if (imm == 0 &&
((cond == eq) || (cond == ne) || (cond == hi) || (cond == ls) ||
(cond == lt) || (cond == ge))) { // One instruction generated
ASSERT_EQ(kInstrSize, __ SizeOfCodeGeneratedSince(&start));
} else { // Two instructions generated
ASSERT_EQ(static_cast<uint8_t>(2 * kInstrSize),
__ SizeOfCodeGeneratedSince(&start));
}
__ Cmp(x0, Immediate(imm));
__ Check(NegateCondition(cond),
AbortReason::kNoReason); // cond must not hold
__ Ret();
__ Bind(&lab); // Branch leads here
__ Cmp(x0, Immediate(imm));
__ Check(cond, AbortReason::kNoReason); // cond must hold
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
}
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
TRACED_FOREACH(int, n, kTestCases) { f.Call(n); }
}
}
}
struct MoveObjectAndSlotTestCase {
const char* comment;
Register dst_object;
Register dst_slot;
Register object;
Register offset_register = no_reg;
};
const MoveObjectAndSlotTestCase kMoveObjectAndSlotTestCases[] = {
{"no overlap", x0, x1, x2},
{"no overlap", x0, x1, x2, x3},
{"object == dst_object", x2, x1, x2},
{"object == dst_object", x2, x1, x2, x3},
{"object == dst_slot", x1, x2, x2},
{"object == dst_slot", x1, x2, x2, x3},
{"offset == dst_object", x0, x1, x2, x0},
{"offset == dst_object && object == dst_slot", x0, x1, x1, x0},
{"offset == dst_slot", x0, x1, x2, x1},
{"offset == dst_slot && object == dst_object", x0, x1, x0, x1}};
// Make sure we include offsets that cannot be encoded in an add instruction.
const int kOffsets[] = {0, 42, kMaxRegularHeapObjectSize, 0x101001};
template <typename T>
class MacroAssemblerTestWithParam : public MacroAssemblerTest,
public ::testing::WithParamInterface<T> {};
using MacroAssemblerTestMoveObjectAndSlot =
MacroAssemblerTestWithParam<MoveObjectAndSlotTestCase>;
TEST_P(MacroAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
const MoveObjectAndSlotTestCase test_case = GetParam();
TRACED_FOREACH(int32_t, offset, kOffsets) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
{
AssemblerBufferWriteScope rw_buffer_scope(*buffer);
__ CodeEntry();
__ Push(x0, padreg);
__ Mov(test_case.object, x1);
Register src_object = test_case.object;
Register dst_object = test_case.dst_object;
Register dst_slot = test_case.dst_slot;
Operand offset_operand(0);
if (test_case.offset_register == no_reg) {
offset_operand = Operand(offset);
} else {
__ Mov(test_case.offset_register, Operand(offset));
offset_operand = Operand(test_case.offset_register);
}
std::stringstream comment;
comment << "-- " << test_case.comment << ": MoveObjectAndSlot("
<< dst_object << ", " << dst_slot << ", " << src_object << ", ";
if (test_case.offset_register == no_reg) {
comment << "#" << offset;
} else {
comment << test_case.offset_register;
}
comment << ") --";
__ RecordComment(comment.str().c_str());
__ MoveObjectAndSlot(dst_object, dst_slot, src_object, offset_operand);
__ RecordComment("--");
// The `result` pointer was saved on the stack.
UseScratchRegisterScope temps(&masm);
Register scratch = temps.AcquireX();
__ Pop(padreg, scratch);
__ Str(dst_object, MemOperand(scratch));
__ Str(dst_slot, MemOperand(scratch, kSystemPointerSize));
__ Ret();
CodeDesc desc;
masm.GetCode(static_cast<LocalIsolate*>(nullptr), &desc);
if (v8_flags.print_code) {
Handle<Code> code =
Factory::CodeBuilder(isolate(), desc, CodeKind::FOR_TESTING)
.Build();
StdoutStream os;
Print(*code, os);
}
}
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, uint8_t**, uint8_t*>::FromBuffer(
isolate(), buffer->start());
uint8_t* object = new uint8_t[offset];
uint8_t* result[] = {nullptr, nullptr};
f.Call(result, object);
// The first element must be the address of the object, and the second the
// slot addressed by `offset`.
EXPECT_EQ(result[0], &object[0]);
EXPECT_EQ(result[1], &object[offset]);
delete[] object;
}
}
INSTANTIATE_TEST_SUITE_P(MacroAssemblerTest,
MacroAssemblerTestMoveObjectAndSlot,
::testing::ValuesIn(kMoveObjectAndSlotTestCases));
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,150 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the ia32 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
// Initialize the root register, as we need it for `Abort()`. Since `Abort()`
// does not return properly, we don't need to restore `kRootRegister`, even
// though it's a callee-saved register.
__ LoadAddress(kRootRegister, ExternalReference::isolate_root(isolate()));
__ set_root_array_available(true);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
// Initialize the root register, as we need it for `Check()`.
// Save the value in `kRootRegister` to restore it later after the call. In
// some configurations `kRootRegister` is callee-saved for C++.
__ mov(ecx, kRootRegister);
__ LoadAddress(kRootRegister, ExternalReference::isolate_root(isolate()));
__ set_root_array_available(true);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ mov(eax, 17);
__ cmp(eax, Operand(esp, 4)); // compare with 1st parameter.
__ Check(Condition::not_equal, AbortReason::kNoReason);
// Restore the original value of `kRootRegister`.
__ mov(kRootRegister, ecx);
__ ret(0);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestPCRelLea) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
// Initialize the root register, as we need it for `Check()`.
// Save the value in `kRootRegister` to restore it later after the call. In
// some configurations `kRootRegister` is callee-saved for C++.
__ mov(edi, kRootRegister);
__ LoadAddress(kRootRegister, ExternalReference::isolate_root(isolate()));
__ set_root_array_available(true);
__ set_abort_hard(true);
Label pt;
__ LoadLabelAddress(ecx, &pt);
__ mov(eax, 42);
__ call(ecx);
__ cmp(eax, 56);
__ Check(Condition::equal, AbortReason::kNoReason);
// Restore the original value of `kRootRegister`.
__ mov(kRootRegister, edi);
__ ret(0);
__ bind(&pt);
__ mov(eax, 56);
__ ret(0);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
}
TEST_F(MacroAssemblerTest, TestDefinedPCRelLea) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
// Initialize the root register, as we need it for `Check()`.
// Save the value in `kRootRegister` to restore it later after the call. In
// some configurations `kRootRegister` is callee-saved for C++.
__ mov(edi, kRootRegister);
__ LoadAddress(kRootRegister, ExternalReference::isolate_root(isolate()));
__ set_root_array_available(true);
__ set_abort_hard(true);
Label pt, start;
__ jmp(&start);
__ bind(&pt);
__ mov(eax, 56);
__ ret(0);
__ bind(&start);
__ LoadLabelAddress(ecx, &pt);
__ mov(eax, 42);
__ call(ecx);
__ cmp(eax, 56);
__ Check(Condition::equal, AbortReason::kNoReason);
// Restore the original value of `kRootRegister`.
__ mov(kRootRegister, edi);
__ ret(0);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,66 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/loong64/assembler-loong64-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the loong64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter (in {a0}) is 17.
__ Check(Condition::ne, AbortReason::kNoReason, a0, Operand(17));
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,68 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/macro-assembler.h"
#include "src/codegen/mips64/assembler-mips64-inl.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter (in {a0}) is 17.
__ Check(Condition::ne, AbortReason::kNoReason, a0, Operand(17));
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,133 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/macro-assembler.h"
#include "src/codegen/ppc/assembler-ppc-inl.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the ppc assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ mov(r4, Operand(17));
__ cmp(r3, r4); // 1st parameter is in {r3}.
__ Check(Condition::ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, ReverseBitsU64) {
struct {
uint64_t expected;
uint64_t input;
} values[] = {
{0x0000000000000000, 0x0000000000000000},
{0xffffffffffffffff, 0xffffffffffffffff},
{0x8000000000000000, 0x0000000000000001},
{0x0000000000000001, 0x8000000000000000},
{0x800066aa22cc4488, 0x1122334455660001},
{0x1122334455660001, 0x800066aa22cc4488},
{0xffffffff00000000, 0x00000000ffffffff},
{0x00000000ffffffff, 0xffffffff00000000},
{0xff01020304050607, 0xe060a020c04080ff},
{0xe060a020c04080ff, 0xff01020304050607},
};
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Push(r4, r5);
__ ReverseBitsU64(r3, r3, r4, r5);
__ Pop(r4, r5);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f =
GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(), buffer->start());
for (unsigned int i = 0; i < (sizeof(values) / sizeof(values[0])); i++) {
CHECK_EQ(values[i].expected, f.Call(values[i].input));
}
}
TEST_F(MacroAssemblerTest, ReverseBitsU32) {
struct {
uint64_t expected;
uint64_t input;
} values[] = {
{0x00000000, 0x00000000}, {0xffffffff, 0xffffffff},
{0x00000001, 0x80000000}, {0x80000000, 0x00000001},
{0x22334455, 0xaa22cc44}, {0xaa22cc44, 0x22334455},
};
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Push(r4, r5);
__ ReverseBitsU32(r3, r3, r4, r5);
__ Pop(r4, r5);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
auto f =
GeneratedCode<uint64_t, uint64_t>::FromBuffer(isolate(), buffer->start());
for (unsigned int i = 0; i < (sizeof(values) / sizeof(values[0])); i++) {
CHECK_EQ(values[i].expected, f.Call(values[i].input));
}
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,66 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(static_cast<LocalIsolate*>(nullptr), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter (in {a0}) is 17.
__ Check(Condition::ne, AbortReason::kNoReason, a0, Operand(17));
__ Ret();
CodeDesc desc;
masm.GetCode(static_cast<LocalIsolate*>(nullptr), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
#undef __
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,70 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/macro-assembler.h"
#include "src/codegen/s390/assembler-s390-inl.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
#define __ masm.
// Test the s390 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
class MacroAssemblerTest : public TestWithIsolate {};
TEST_F(MacroAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(); }, v8_flags.debug_code ? "abort: no reason" : "");
}
TEST_F(MacroAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
__ lgfi(r3, Operand(17));
__ CmpS64(r2, r3); // 1st parameter is in {r2}.
__ Check(Condition::ne, AbortReason::kNoReason);
__ Ret();
CodeDesc desc;
masm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
ASSERT_DEATH_IF_SUPPORTED(
{ f.Call(17); }, v8_flags.debug_code ? "abort: no reason" : "");
}
#undef __
} // namespace internal
} // namespace v8

File diff suppressed because it is too large Load Diff