14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/assembler/x64/assembler_x64.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_cinamespace panda::ecmascript::x64 {
194514f5e3Sopenharmony_civoid AssemblerX64::Pushq(Register x)
204514f5e3Sopenharmony_ci{
214514f5e3Sopenharmony_ci    EmitRexPrefix(x);
224514f5e3Sopenharmony_ci    // 0x50: Push r16
234514f5e3Sopenharmony_ci    EmitU8(0x50 | LowBits(x));
244514f5e3Sopenharmony_ci}
254514f5e3Sopenharmony_ci
264514f5e3Sopenharmony_civoid AssemblerX64::Pushq(Immediate x)
274514f5e3Sopenharmony_ci{
284514f5e3Sopenharmony_ci    if (InRange8(x.Value())) {
294514f5e3Sopenharmony_ci        // 6A: Push imm8
304514f5e3Sopenharmony_ci        EmitU8(0x6A);
314514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(x.Value()));
324514f5e3Sopenharmony_ci    } else {
334514f5e3Sopenharmony_ci        // 68: Push imm32
344514f5e3Sopenharmony_ci        EmitU8(0x68);
354514f5e3Sopenharmony_ci        EmitI32(x.Value());
364514f5e3Sopenharmony_ci    }
374514f5e3Sopenharmony_ci}
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_civoid AssemblerX64::Push(Register x)
404514f5e3Sopenharmony_ci{
414514f5e3Sopenharmony_ci    Pushq(x);
424514f5e3Sopenharmony_ci}
434514f5e3Sopenharmony_ci
444514f5e3Sopenharmony_civoid AssemblerX64::Popq(Register x)
454514f5e3Sopenharmony_ci{
464514f5e3Sopenharmony_ci    EmitRexPrefix(x);
474514f5e3Sopenharmony_ci    // 0x58: Pop r16
484514f5e3Sopenharmony_ci    EmitU8(0x58 | LowBits(x));
494514f5e3Sopenharmony_ci}
504514f5e3Sopenharmony_ci
514514f5e3Sopenharmony_civoid AssemblerX64::Pop(Register x)
524514f5e3Sopenharmony_ci{
534514f5e3Sopenharmony_ci    Popq(x);
544514f5e3Sopenharmony_ci}
554514f5e3Sopenharmony_ci
564514f5e3Sopenharmony_ci
574514f5e3Sopenharmony_civoid AssemblerX64::Addq(Immediate src, Register dst)
584514f5e3Sopenharmony_ci{
594514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
604514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
614514f5e3Sopenharmony_ci        // 83: Add r/m16, imm8
624514f5e3Sopenharmony_ci        EmitU8(0x83);
634514f5e3Sopenharmony_ci        // 0: 83 /0 ib
644514f5e3Sopenharmony_ci        EmitModrm(0, dst);
654514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
664514f5e3Sopenharmony_ci    } else if (dst == rax) {
674514f5e3Sopenharmony_ci        // 0x5: Add rax, imm32
684514f5e3Sopenharmony_ci        EmitU8(0x5);
694514f5e3Sopenharmony_ci        EmitI32(src.Value());
704514f5e3Sopenharmony_ci    } else {
714514f5e3Sopenharmony_ci        // 81: Add r/m32, imm32
724514f5e3Sopenharmony_ci        EmitU8(0x81);
734514f5e3Sopenharmony_ci        // 0: 81 /0 id
744514f5e3Sopenharmony_ci        EmitModrm(0, dst);
754514f5e3Sopenharmony_ci        EmitI32(src.Value());
764514f5e3Sopenharmony_ci    }
774514f5e3Sopenharmony_ci}
784514f5e3Sopenharmony_ci
794514f5e3Sopenharmony_civoid AssemblerX64::Addq(Register src, Register dst)
804514f5e3Sopenharmony_ci{
814514f5e3Sopenharmony_ci    EmitRexPrefix(dst, src);
824514f5e3Sopenharmony_ci    // 03 : add r64, r/m64
834514f5e3Sopenharmony_ci    EmitU8(0x03);
844514f5e3Sopenharmony_ci    EmitModrm(dst, src);
854514f5e3Sopenharmony_ci}
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_civoid AssemblerX64::Addl(Immediate src, Register dst)
884514f5e3Sopenharmony_ci{
894514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
904514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
914514f5e3Sopenharmony_ci        // 83: Add r/m16, imm8
924514f5e3Sopenharmony_ci        EmitU8(0x83);
934514f5e3Sopenharmony_ci        // 0: 83 /0 ib
944514f5e3Sopenharmony_ci        EmitModrm(0, dst);
954514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
964514f5e3Sopenharmony_ci    } else if (dst == rax) {
974514f5e3Sopenharmony_ci        // 0x5: Add rax, imm32
984514f5e3Sopenharmony_ci        EmitU8(0x5);
994514f5e3Sopenharmony_ci        EmitI32(src.Value());
1004514f5e3Sopenharmony_ci    } else {
1014514f5e3Sopenharmony_ci        // 81: Add r/m32, imm32
1024514f5e3Sopenharmony_ci        EmitU8(0x81);
1034514f5e3Sopenharmony_ci        // 0: 81 /0 id
1044514f5e3Sopenharmony_ci        EmitModrm(0, dst);
1054514f5e3Sopenharmony_ci        EmitI32(src.Value());
1064514f5e3Sopenharmony_ci    }
1074514f5e3Sopenharmony_ci}
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_civoid AssemblerX64::Subq(Immediate src, Register dst)
1104514f5e3Sopenharmony_ci{
1114514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
1124514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
1134514f5e3Sopenharmony_ci        // 83: Sub r/m16, imm8
1144514f5e3Sopenharmony_ci        EmitU8(0x83);
1154514f5e3Sopenharmony_ci        // 5: 83 /5 ib
1164514f5e3Sopenharmony_ci        EmitModrm(5, dst);
1174514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
1184514f5e3Sopenharmony_ci    } else if (dst == rax) {
1194514f5e3Sopenharmony_ci        // 0x2D: Sub rax, imm32
1204514f5e3Sopenharmony_ci        EmitU8(0x2D);
1214514f5e3Sopenharmony_ci        EmitI32(src.Value());
1224514f5e3Sopenharmony_ci    } else {
1234514f5e3Sopenharmony_ci        // 81: sub r/m32, imm32
1244514f5e3Sopenharmony_ci        EmitU8(0x81);
1254514f5e3Sopenharmony_ci        // 5: 81 /5 id
1264514f5e3Sopenharmony_ci        EmitModrm(5, dst);
1274514f5e3Sopenharmony_ci        EmitI32(src.Value());
1284514f5e3Sopenharmony_ci    }
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_civoid AssemblerX64::Subq(Register src, Register dst)
1324514f5e3Sopenharmony_ci{
1334514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
1344514f5e3Sopenharmony_ci    // 29: sub r/m64, r64
1354514f5e3Sopenharmony_ci    EmitU8(0x29);
1364514f5e3Sopenharmony_ci    EmitModrm(src, dst);
1374514f5e3Sopenharmony_ci}
1384514f5e3Sopenharmony_ci
1394514f5e3Sopenharmony_civoid AssemblerX64::Subl(Immediate src, Register dst)
1404514f5e3Sopenharmony_ci{
1414514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
1424514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
1434514f5e3Sopenharmony_ci        // 83: Sub r/m16, imm8
1444514f5e3Sopenharmony_ci        EmitU8(0x83);
1454514f5e3Sopenharmony_ci        // 5: 83 /5 ib
1464514f5e3Sopenharmony_ci        EmitModrm(5, dst);
1474514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
1484514f5e3Sopenharmony_ci    } else if (dst == rax) {
1494514f5e3Sopenharmony_ci        // 0x2D: Sub eax, imm32
1504514f5e3Sopenharmony_ci        EmitU8(0x2D);
1514514f5e3Sopenharmony_ci        EmitI32(src.Value());
1524514f5e3Sopenharmony_ci    } else {
1534514f5e3Sopenharmony_ci        // 81: sub r/m32, imm32
1544514f5e3Sopenharmony_ci        EmitU8(0x81);
1554514f5e3Sopenharmony_ci        // 5: 81 /5 id
1564514f5e3Sopenharmony_ci        EmitModrm(5, dst);
1574514f5e3Sopenharmony_ci        EmitI32(src.Value());
1584514f5e3Sopenharmony_ci    }
1594514f5e3Sopenharmony_ci}
1604514f5e3Sopenharmony_ci
1614514f5e3Sopenharmony_civoid AssemblerX64::Cmpq(Immediate src, Register dst)
1624514f5e3Sopenharmony_ci{
1634514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
1644514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
1654514f5e3Sopenharmony_ci        // 83: cmp r/m64, imm8
1664514f5e3Sopenharmony_ci        EmitU8(0x83);
1674514f5e3Sopenharmony_ci        // 7: 83 /7 ib
1684514f5e3Sopenharmony_ci        EmitModrm(7, dst);
1694514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
1704514f5e3Sopenharmony_ci    } else if (dst == rax) {
1714514f5e3Sopenharmony_ci        // 0x3D: cmp rax, imm32
1724514f5e3Sopenharmony_ci        EmitU8(0x3D);
1734514f5e3Sopenharmony_ci        EmitI32(src.Value());
1744514f5e3Sopenharmony_ci    } else {
1754514f5e3Sopenharmony_ci        // 81: cmp r/m32, imm32
1764514f5e3Sopenharmony_ci        EmitU8(0x81);
1774514f5e3Sopenharmony_ci        // 7: 81 /7 id
1784514f5e3Sopenharmony_ci        EmitModrm(7, dst);
1794514f5e3Sopenharmony_ci        EmitI32(src.Value());
1804514f5e3Sopenharmony_ci    }
1814514f5e3Sopenharmony_ci}
1824514f5e3Sopenharmony_ci
1834514f5e3Sopenharmony_civoid AssemblerX64::Cmpb(Immediate src, Register dst)
1844514f5e3Sopenharmony_ci{
1854514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
1864514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
1874514f5e3Sopenharmony_ci        // 80: cmp r/m8, imm8
1884514f5e3Sopenharmony_ci        EmitU8(0x80);
1894514f5e3Sopenharmony_ci        // 7: /7 ib
1904514f5e3Sopenharmony_ci        EmitModrm(7, dst);
1914514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
1924514f5e3Sopenharmony_ci    } else if (dst == rax) {
1934514f5e3Sopenharmony_ci        // 0x3C: cmp al, imm8
1944514f5e3Sopenharmony_ci        EmitU8(0x3C);
1954514f5e3Sopenharmony_ci        EmitI8(src.Value());
1964514f5e3Sopenharmony_ci    } else {
1974514f5e3Sopenharmony_ci        LOG_ECMA(FATAL) << "this branch is unreachable";
1984514f5e3Sopenharmony_ci        UNREACHABLE();
1994514f5e3Sopenharmony_ci    }
2004514f5e3Sopenharmony_ci}
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_civoid AssemblerX64::Cmpq(Register src, Register dst)
2034514f5e3Sopenharmony_ci{
2044514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
2054514f5e3Sopenharmony_ci    // 39: Cmp r/m64, r64
2064514f5e3Sopenharmony_ci    EmitU8(0x39);
2074514f5e3Sopenharmony_ci    EmitModrm(src, dst);
2084514f5e3Sopenharmony_ci}
2094514f5e3Sopenharmony_ci
2104514f5e3Sopenharmony_civoid AssemblerX64::Cmpl(Immediate src, Register dst)
2114514f5e3Sopenharmony_ci{
2124514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
2134514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
2144514f5e3Sopenharmony_ci        // 83: cmp r/m32, imm8
2154514f5e3Sopenharmony_ci        EmitU8(0x83);
2164514f5e3Sopenharmony_ci        // 7: 83 /7 ib
2174514f5e3Sopenharmony_ci        EmitModrm(7, dst);
2184514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
2194514f5e3Sopenharmony_ci    } else if (dst == rax) {
2204514f5e3Sopenharmony_ci        // 0x3D: cmp rax, imm32
2214514f5e3Sopenharmony_ci        EmitU8(0x3D);
2224514f5e3Sopenharmony_ci        EmitI32(src.Value());
2234514f5e3Sopenharmony_ci    } else {
2244514f5e3Sopenharmony_ci        // 81: cmp r/m32, imm32
2254514f5e3Sopenharmony_ci        EmitU8(0x81);
2264514f5e3Sopenharmony_ci        // 7: 81 /7 id
2274514f5e3Sopenharmony_ci        EmitModrm(7, dst);
2284514f5e3Sopenharmony_ci        EmitI32(src.Value());
2294514f5e3Sopenharmony_ci    }
2304514f5e3Sopenharmony_ci}
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_civoid AssemblerX64::Cmp(Immediate src, Register dst)
2334514f5e3Sopenharmony_ci{
2344514f5e3Sopenharmony_ci    Cmpq(src, dst);
2354514f5e3Sopenharmony_ci}
2364514f5e3Sopenharmony_ci
2374514f5e3Sopenharmony_civoid AssemblerX64::Movq(Register src, Register dst)
2384514f5e3Sopenharmony_ci{
2394514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
2404514f5e3Sopenharmony_ci    // 0x89: Move r16 to r/m16
2414514f5e3Sopenharmony_ci    EmitU8(0x89);
2424514f5e3Sopenharmony_ci    EmitModrm(src, dst);
2434514f5e3Sopenharmony_ci}
2444514f5e3Sopenharmony_ci
2454514f5e3Sopenharmony_civoid AssemblerX64::Mov(Register src, Register dst)
2464514f5e3Sopenharmony_ci{
2474514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
2484514f5e3Sopenharmony_ci    // 0x89: Move r16 to r/m16
2494514f5e3Sopenharmony_ci    EmitU8(0x8B);
2504514f5e3Sopenharmony_ci    EmitModrm(dst, src);
2514514f5e3Sopenharmony_ci}
2524514f5e3Sopenharmony_ci
2534514f5e3Sopenharmony_civoid AssemblerX64::Align16()
2544514f5e3Sopenharmony_ci{
2554514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
2564514f5e3Sopenharmony_ci    // 16: align16
2574514f5e3Sopenharmony_ci    size_t x = 16;
2584514f5e3Sopenharmony_ci    size_t delta = static_cast<size_t>(x - (pos & (x - 1)));
2594514f5e3Sopenharmony_ci    for (size_t i = 0; i < delta; i++) {
2604514f5e3Sopenharmony_ci        // 0x90: NOP
2614514f5e3Sopenharmony_ci        EmitU8(0x90);
2624514f5e3Sopenharmony_ci    }
2634514f5e3Sopenharmony_ci}
2644514f5e3Sopenharmony_ci
2654514f5e3Sopenharmony_civoid AssemblerX64::Movq(const Operand &src, Register dst)
2664514f5e3Sopenharmony_ci{
2674514f5e3Sopenharmony_ci    EmitRexPrefix(dst, src);
2684514f5e3Sopenharmony_ci    // 0x8B: Move r/m64 to r64
2694514f5e3Sopenharmony_ci    EmitU8(0x8B);
2704514f5e3Sopenharmony_ci    EmitOperand(dst, src);
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_civoid AssemblerX64::Movq(Register src, const Operand &dst)
2744514f5e3Sopenharmony_ci{
2754514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
2764514f5e3Sopenharmony_ci    // 0x89: Move r64 to r/m64
2774514f5e3Sopenharmony_ci    EmitU8(0x89);
2784514f5e3Sopenharmony_ci    EmitOperand(src, dst);
2794514f5e3Sopenharmony_ci}
2804514f5e3Sopenharmony_ci
2814514f5e3Sopenharmony_civoid AssemblerX64::Movq(Immediate src, Operand dst)
2824514f5e3Sopenharmony_ci{
2834514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
2844514f5e3Sopenharmony_ci    // 0xC7: Move imm32 to r/m32
2854514f5e3Sopenharmony_ci    EmitU8(0xC7);
2864514f5e3Sopenharmony_ci    // 0: C7 /0 id
2874514f5e3Sopenharmony_ci    EmitOperand(0, dst);
2884514f5e3Sopenharmony_ci    EmitI32(src.Value());
2894514f5e3Sopenharmony_ci}
2904514f5e3Sopenharmony_ci
2914514f5e3Sopenharmony_civoid AssemblerX64::Movq(Immediate src, Register dst)
2924514f5e3Sopenharmony_ci{
2934514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
2944514f5e3Sopenharmony_ci    // B8 : mov r32, imm32
2954514f5e3Sopenharmony_ci    EmitU8(0xB8 | LowBits(dst));
2964514f5e3Sopenharmony_ci    EmitI32(src.Value());
2974514f5e3Sopenharmony_ci}
2984514f5e3Sopenharmony_ci
2994514f5e3Sopenharmony_civoid AssemblerX64::Mov(const Operand &src, Register dst)
3004514f5e3Sopenharmony_ci{
3014514f5e3Sopenharmony_ci    Movq(src, dst);
3024514f5e3Sopenharmony_ci}
3034514f5e3Sopenharmony_ci
3044514f5e3Sopenharmony_civoid AssemblerX64::EmitJmp(int32_t offset)
3054514f5e3Sopenharmony_ci{
3064514f5e3Sopenharmony_ci    offset--;
3074514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3084514f5e3Sopenharmony_ci        // EB: Jmp rel8
3094514f5e3Sopenharmony_ci        EmitU8(0xEB);
3104514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3114514f5e3Sopenharmony_ci    } else {
3124514f5e3Sopenharmony_ci        // E9: Jmp rel32
3134514f5e3Sopenharmony_ci        EmitU8(0xE9);
3144514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3154514f5e3Sopenharmony_ci    }
3164514f5e3Sopenharmony_ci}
3174514f5e3Sopenharmony_ci
3184514f5e3Sopenharmony_civoid AssemblerX64::EmitJa(int32_t offset)
3194514f5e3Sopenharmony_ci{
3204514f5e3Sopenharmony_ci    offset--;
3214514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3224514f5e3Sopenharmony_ci        // 77 : Ja rel8
3234514f5e3Sopenharmony_ci        EmitU8(0x77);
3244514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3254514f5e3Sopenharmony_ci    } else {
3264514f5e3Sopenharmony_ci        offset--;
3274514f5e3Sopenharmony_ci        // 0F 87 : ja rel32
3284514f5e3Sopenharmony_ci        EmitU8(0x0F);
3294514f5e3Sopenharmony_ci        EmitU8(0x87);
3304514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3314514f5e3Sopenharmony_ci    }
3324514f5e3Sopenharmony_ci}
3334514f5e3Sopenharmony_ci
3344514f5e3Sopenharmony_civoid AssemblerX64::EmitJb(int32_t offset)
3354514f5e3Sopenharmony_ci{
3364514f5e3Sopenharmony_ci    offset--;
3374514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3384514f5e3Sopenharmony_ci        // 72 : Jb rel8
3394514f5e3Sopenharmony_ci        EmitU8(0x72);
3404514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3414514f5e3Sopenharmony_ci    } else {
3424514f5e3Sopenharmony_ci        offset--;
3434514f5e3Sopenharmony_ci        // 0F 82 : Jb rel32
3444514f5e3Sopenharmony_ci        EmitU8(0x0F);
3454514f5e3Sopenharmony_ci        EmitU8(0x82);
3464514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3474514f5e3Sopenharmony_ci    }
3484514f5e3Sopenharmony_ci}
3494514f5e3Sopenharmony_ci
3504514f5e3Sopenharmony_civoid AssemblerX64::EmitJz(int32_t offset)
3514514f5e3Sopenharmony_ci{
3524514f5e3Sopenharmony_ci    offset--;
3534514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3544514f5e3Sopenharmony_ci        // 74 : Jz rel8
3554514f5e3Sopenharmony_ci        EmitU8(0x74);
3564514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3574514f5e3Sopenharmony_ci    } else {
3584514f5e3Sopenharmony_ci        offset--;
3594514f5e3Sopenharmony_ci        // 0F 84 : Jz rel32
3604514f5e3Sopenharmony_ci        EmitU8(0x0F);
3614514f5e3Sopenharmony_ci        EmitU8(0x84);
3624514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3634514f5e3Sopenharmony_ci    }
3644514f5e3Sopenharmony_ci}
3654514f5e3Sopenharmony_ci
3664514f5e3Sopenharmony_civoid AssemblerX64::EmitJne(int32_t offset)
3674514f5e3Sopenharmony_ci{
3684514f5e3Sopenharmony_ci    offset--;
3694514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3704514f5e3Sopenharmony_ci        // 75 : Jne rel8;
3714514f5e3Sopenharmony_ci        EmitU8(0x75);
3724514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3734514f5e3Sopenharmony_ci    } else {
3744514f5e3Sopenharmony_ci        offset--;
3754514f5e3Sopenharmony_ci        // 0F 85 : Jne rel32
3764514f5e3Sopenharmony_ci        EmitU8(0x0F);
3774514f5e3Sopenharmony_ci        EmitU8(0x85);
3784514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3794514f5e3Sopenharmony_ci    }
3804514f5e3Sopenharmony_ci}
3814514f5e3Sopenharmony_ci
3824514f5e3Sopenharmony_civoid AssemblerX64::EmitJbe(int32_t offset)
3834514f5e3Sopenharmony_ci{
3844514f5e3Sopenharmony_ci    offset--;
3854514f5e3Sopenharmony_ci    if (InRange8(offset - SIZE_OF_INT8)) {
3864514f5e3Sopenharmony_ci        // 76 : Jbe rel8;
3874514f5e3Sopenharmony_ci        EmitU8(0x76);
3884514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
3894514f5e3Sopenharmony_ci    } else {
3904514f5e3Sopenharmony_ci        offset--;
3914514f5e3Sopenharmony_ci        // 0F 86 : Jne rel32
3924514f5e3Sopenharmony_ci        EmitU8(0x0F);
3934514f5e3Sopenharmony_ci        EmitU8(0x86);
3944514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
3954514f5e3Sopenharmony_ci    }
3964514f5e3Sopenharmony_ci}
3974514f5e3Sopenharmony_ci
3984514f5e3Sopenharmony_civoid AssemblerX64::EmitJnz(int32_t offset)
3994514f5e3Sopenharmony_ci{
4004514f5e3Sopenharmony_ci    offset--;
4014514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4024514f5e3Sopenharmony_ci        // 75 : Jnz rel8
4034514f5e3Sopenharmony_ci        EmitU8(0x75);
4044514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4054514f5e3Sopenharmony_ci    } else {
4064514f5e3Sopenharmony_ci        offset--;
4074514f5e3Sopenharmony_ci        // 0F 85: Jnz rel32
4084514f5e3Sopenharmony_ci        EmitU8(0x0F);
4094514f5e3Sopenharmony_ci        EmitU8(0x85);
4104514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4114514f5e3Sopenharmony_ci    }
4124514f5e3Sopenharmony_ci}
4134514f5e3Sopenharmony_ci
4144514f5e3Sopenharmony_civoid AssemblerX64::EmitJle(int32_t offset)
4154514f5e3Sopenharmony_ci{
4164514f5e3Sopenharmony_ci    offset--;
4174514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4184514f5e3Sopenharmony_ci        // 7E : Jle rel8
4194514f5e3Sopenharmony_ci        EmitU8(0x7E);
4204514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4214514f5e3Sopenharmony_ci    } else {
4224514f5e3Sopenharmony_ci        offset--;
4234514f5e3Sopenharmony_ci        // 0F 8E: Jle rel32
4244514f5e3Sopenharmony_ci        EmitU8(0x0F);
4254514f5e3Sopenharmony_ci        EmitU8(0x8E);
4264514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4274514f5e3Sopenharmony_ci    }
4284514f5e3Sopenharmony_ci}
4294514f5e3Sopenharmony_ci
4304514f5e3Sopenharmony_civoid AssemblerX64::EmitJae(int32_t offset)
4314514f5e3Sopenharmony_ci{
4324514f5e3Sopenharmony_ci    offset--;
4334514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4344514f5e3Sopenharmony_ci        // 73 : Jae rel8
4354514f5e3Sopenharmony_ci        EmitU8(0x73);
4364514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4374514f5e3Sopenharmony_ci    } else {
4384514f5e3Sopenharmony_ci        offset--;
4394514f5e3Sopenharmony_ci        // 0F 83: Jae rel32
4404514f5e3Sopenharmony_ci        EmitU8(0x0F);
4414514f5e3Sopenharmony_ci        EmitU8(0x83);
4424514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4434514f5e3Sopenharmony_ci    }
4444514f5e3Sopenharmony_ci}
4454514f5e3Sopenharmony_ci
4464514f5e3Sopenharmony_civoid AssemblerX64::EmitJg(int32_t offset)
4474514f5e3Sopenharmony_ci{
4484514f5e3Sopenharmony_ci    offset--;
4494514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4504514f5e3Sopenharmony_ci        // 7F : Jg rel8
4514514f5e3Sopenharmony_ci        EmitU8(0x7F);
4524514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4534514f5e3Sopenharmony_ci    } else {
4544514f5e3Sopenharmony_ci        offset--;
4554514f5e3Sopenharmony_ci        // 0F 8F: Jg rel32
4564514f5e3Sopenharmony_ci        EmitU8(0x0F);
4574514f5e3Sopenharmony_ci        EmitU8(0x8F);
4584514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4594514f5e3Sopenharmony_ci    }
4604514f5e3Sopenharmony_ci}
4614514f5e3Sopenharmony_ci
4624514f5e3Sopenharmony_civoid AssemblerX64::EmitJge(int32_t offset)
4634514f5e3Sopenharmony_ci{
4644514f5e3Sopenharmony_ci    offset--;
4654514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4664514f5e3Sopenharmony_ci        // 7D : Jg rel8
4674514f5e3Sopenharmony_ci        EmitU8(0x7D);
4684514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4694514f5e3Sopenharmony_ci    } else {
4704514f5e3Sopenharmony_ci        offset--;
4714514f5e3Sopenharmony_ci        // 0F 8F: Jg rel32
4724514f5e3Sopenharmony_ci        EmitU8(0x0F);
4734514f5e3Sopenharmony_ci        EmitU8(0x8D);
4744514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4754514f5e3Sopenharmony_ci    }
4764514f5e3Sopenharmony_ci}
4774514f5e3Sopenharmony_ci
4784514f5e3Sopenharmony_civoid AssemblerX64::EmitJe(int32_t offset)
4794514f5e3Sopenharmony_ci{
4804514f5e3Sopenharmony_ci    offset--;
4814514f5e3Sopenharmony_ci    if (InRange8(offset)) {
4824514f5e3Sopenharmony_ci        // 74 : Je rel8
4834514f5e3Sopenharmony_ci        EmitU8(0x74);
4844514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
4854514f5e3Sopenharmony_ci    } else {
4864514f5e3Sopenharmony_ci        offset--;
4874514f5e3Sopenharmony_ci        // 0F 84: Je rel32
4884514f5e3Sopenharmony_ci        EmitU8(0x0F);
4894514f5e3Sopenharmony_ci        EmitU8(0x84);
4904514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
4914514f5e3Sopenharmony_ci    }
4924514f5e3Sopenharmony_ci}
4934514f5e3Sopenharmony_ci
4944514f5e3Sopenharmony_civoid AssemblerX64::EmitCall(int32_t offset)
4954514f5e3Sopenharmony_ci{
4964514f5e3Sopenharmony_ci    offset--;
4974514f5e3Sopenharmony_ci    // E8: call rel32
4984514f5e3Sopenharmony_ci    EmitU8(0xE8);
4994514f5e3Sopenharmony_ci    EmitI32(offset - SIZE_OF_INT32);
5004514f5e3Sopenharmony_ci}
5014514f5e3Sopenharmony_ci
5024514f5e3Sopenharmony_civoid AssemblerX64::EmitJnb(int32_t offset)
5034514f5e3Sopenharmony_ci{
5044514f5e3Sopenharmony_ci    offset--;
5054514f5e3Sopenharmony_ci    if (InRange8(offset)) {
5064514f5e3Sopenharmony_ci        // 73 : Jnb rel8
5074514f5e3Sopenharmony_ci        EmitU8(0x73);
5084514f5e3Sopenharmony_ci        EmitI8(offset - SIZE_OF_INT8);
5094514f5e3Sopenharmony_ci    } else {
5104514f5e3Sopenharmony_ci        offset--;
5114514f5e3Sopenharmony_ci        // 0F 83: Jnb rel32
5124514f5e3Sopenharmony_ci        EmitU8(0x0F);
5134514f5e3Sopenharmony_ci        EmitU8(0x83);
5144514f5e3Sopenharmony_ci        EmitI32(offset - SIZE_OF_INT32);
5154514f5e3Sopenharmony_ci    }
5164514f5e3Sopenharmony_ci}
5174514f5e3Sopenharmony_ci
5184514f5e3Sopenharmony_civoid AssemblerX64::Callq(Register addr)
5194514f5e3Sopenharmony_ci{
5204514f5e3Sopenharmony_ci    // C3: RET Near return to calling procedure
5214514f5e3Sopenharmony_ci    EmitRexPrefix(addr);
5224514f5e3Sopenharmony_ci    // FF: Call r/m16
5234514f5e3Sopenharmony_ci    EmitU8(0xFF);
5244514f5e3Sopenharmony_ci    // 0x2: FF /2
5254514f5e3Sopenharmony_ci    EmitModrm(0x2, addr);
5264514f5e3Sopenharmony_ci}
5274514f5e3Sopenharmony_ci
5284514f5e3Sopenharmony_civoid AssemblerX64::Callq(Label *target)
5294514f5e3Sopenharmony_ci{
5304514f5e3Sopenharmony_ci    if (target->IsBound()) {
5314514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
5324514f5e3Sopenharmony_ci        EmitCall(offset);
5334514f5e3Sopenharmony_ci        return;
5344514f5e3Sopenharmony_ci    }
5354514f5e3Sopenharmony_ci
5364514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
5374514f5e3Sopenharmony_ci    int32_t emitPos = 0;
5384514f5e3Sopenharmony_ci    if (target->IsLinked()) {
5394514f5e3Sopenharmony_ci        emitPos = static_cast<int32_t>(target->GetLinkedPos());
5404514f5e3Sopenharmony_ci    }
5414514f5e3Sopenharmony_ci    // +1: skip opcode
5424514f5e3Sopenharmony_ci    target->LinkTo(pos + 1);
5434514f5e3Sopenharmony_ci    // E8: call rel32
5444514f5e3Sopenharmony_ci    EmitU8(0xE8);
5454514f5e3Sopenharmony_ci    EmitI32(emitPos);
5464514f5e3Sopenharmony_ci}
5474514f5e3Sopenharmony_ci
5484514f5e3Sopenharmony_civoid AssemblerX64::Ret()
5494514f5e3Sopenharmony_ci{
5504514f5e3Sopenharmony_ci    // C3: RET Near return to calling procedure
5514514f5e3Sopenharmony_ci    EmitU8(0xC3);
5524514f5e3Sopenharmony_ci}
5534514f5e3Sopenharmony_ci
5544514f5e3Sopenharmony_civoid AssemblerX64::Jmp(Label *target, Distance distance)
5554514f5e3Sopenharmony_ci{
5564514f5e3Sopenharmony_ci    if (target->IsBound()) {
5574514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
5584514f5e3Sopenharmony_ci        EmitJmp(offset);
5594514f5e3Sopenharmony_ci        return;
5604514f5e3Sopenharmony_ci    }
5614514f5e3Sopenharmony_ci
5624514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
5634514f5e3Sopenharmony_ci    int32_t emitPos = 0;
5644514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
5654514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
5664514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
5674514f5e3Sopenharmony_ci        }
5684514f5e3Sopenharmony_ci        // +1: skip opcode
5694514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
5704514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
5714514f5e3Sopenharmony_ci        // EB: Jmp rel8
5724514f5e3Sopenharmony_ci        EmitU8(0xEB);
5734514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
5744514f5e3Sopenharmony_ci    } else {
5754514f5e3Sopenharmony_ci        if (target->IsLinked()) {
5764514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
5774514f5e3Sopenharmony_ci        }
5784514f5e3Sopenharmony_ci        // +1: skip opcode
5794514f5e3Sopenharmony_ci        target->LinkTo(pos + 1);
5804514f5e3Sopenharmony_ci        // E9: Jmp rel32
5814514f5e3Sopenharmony_ci        EmitU8(0xE9);
5824514f5e3Sopenharmony_ci        EmitI32(emitPos);
5834514f5e3Sopenharmony_ci    }
5844514f5e3Sopenharmony_ci}
5854514f5e3Sopenharmony_ci
5864514f5e3Sopenharmony_civoid AssemblerX64::Jmp(Register dst)
5874514f5e3Sopenharmony_ci{
5884514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
5894514f5e3Sopenharmony_ci    // opcode FF/4 : jmp r/m64
5904514f5e3Sopenharmony_ci    EmitU8(0xFF);
5914514f5e3Sopenharmony_ci    // 4 means register
5924514f5e3Sopenharmony_ci    EmitModrm(4, dst);
5934514f5e3Sopenharmony_ci}
5944514f5e3Sopenharmony_ci
5954514f5e3Sopenharmony_civoid AssemblerX64::Jmp(Immediate offset)
5964514f5e3Sopenharmony_ci{
5974514f5e3Sopenharmony_ci    if (InRange8(offset.Value())) {
5984514f5e3Sopenharmony_ci        // opcode EB : jmp rel8
5994514f5e3Sopenharmony_ci        EmitU8(0xEB);
6004514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(offset.Value()));
6014514f5e3Sopenharmony_ci    } else {
6024514f5e3Sopenharmony_ci        // opcode E9 : jmp rel32
6034514f5e3Sopenharmony_ci        EmitU8(0xE9);
6044514f5e3Sopenharmony_ci        EmitI32(offset.Value());
6054514f5e3Sopenharmony_ci    }
6064514f5e3Sopenharmony_ci}
6074514f5e3Sopenharmony_ci
6084514f5e3Sopenharmony_civoid AssemblerX64::Ja(Label *target, Distance distance)
6094514f5e3Sopenharmony_ci{
6104514f5e3Sopenharmony_ci    if (target->IsBound()) {
6114514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
6124514f5e3Sopenharmony_ci        EmitJa(offset);
6134514f5e3Sopenharmony_ci        return;
6144514f5e3Sopenharmony_ci    }
6154514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
6164514f5e3Sopenharmony_ci    int32_t emitPos = 0;
6174514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
6184514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
6194514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
6204514f5e3Sopenharmony_ci        }
6214514f5e3Sopenharmony_ci        // +1: skip opcode
6224514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
6234514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
6244514f5e3Sopenharmony_ci        // 77: ja rel8
6254514f5e3Sopenharmony_ci        EmitU8(0x77);
6264514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
6274514f5e3Sopenharmony_ci    } else {
6284514f5e3Sopenharmony_ci        if (target->IsLinked()) {
6294514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
6304514f5e3Sopenharmony_ci        }
6314514f5e3Sopenharmony_ci        // 2: skip opcode
6324514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
6334514f5e3Sopenharmony_ci        // 0F 87: ja rel32
6344514f5e3Sopenharmony_ci        EmitU8(0X0F);
6354514f5e3Sopenharmony_ci        EmitU8(0x87);
6364514f5e3Sopenharmony_ci        EmitI32(emitPos);
6374514f5e3Sopenharmony_ci    }
6384514f5e3Sopenharmony_ci}
6394514f5e3Sopenharmony_ci
6404514f5e3Sopenharmony_civoid AssemblerX64::Jb(Label *target, Distance distance)
6414514f5e3Sopenharmony_ci{
6424514f5e3Sopenharmony_ci    if (target->IsBound()) {
6434514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
6444514f5e3Sopenharmony_ci        EmitJb(offset);
6454514f5e3Sopenharmony_ci        return;
6464514f5e3Sopenharmony_ci    }
6474514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
6484514f5e3Sopenharmony_ci    int32_t emitPos = 0;
6494514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
6504514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
6514514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
6524514f5e3Sopenharmony_ci        }
6534514f5e3Sopenharmony_ci        // +1: skip opcode
6544514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
6554514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
6564514f5e3Sopenharmony_ci        // 72 : Jb rel8
6574514f5e3Sopenharmony_ci        EmitU8(0x72);
6584514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
6594514f5e3Sopenharmony_ci    } else {
6604514f5e3Sopenharmony_ci        if (target->IsLinked()) {
6614514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
6624514f5e3Sopenharmony_ci        }
6634514f5e3Sopenharmony_ci        // 2: skip opcode
6644514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
6654514f5e3Sopenharmony_ci        // 0F 82: jb rel32
6664514f5e3Sopenharmony_ci        EmitU8(0X0F);
6674514f5e3Sopenharmony_ci        EmitU8(0x82);
6684514f5e3Sopenharmony_ci        EmitI32(emitPos);
6694514f5e3Sopenharmony_ci    }
6704514f5e3Sopenharmony_ci}
6714514f5e3Sopenharmony_civoid AssemblerX64::Jz(Label *target, Distance distance)
6724514f5e3Sopenharmony_ci{
6734514f5e3Sopenharmony_ci    if (target->IsBound()) {
6744514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
6754514f5e3Sopenharmony_ci        EmitJz(offset);
6764514f5e3Sopenharmony_ci        return;
6774514f5e3Sopenharmony_ci    }
6784514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
6794514f5e3Sopenharmony_ci    int32_t emitPos = 0;
6804514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
6814514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
6824514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
6834514f5e3Sopenharmony_ci        }
6844514f5e3Sopenharmony_ci        // +1: skip opcode
6854514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
6864514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
6874514f5e3Sopenharmony_ci        // 74 : Jz rel8
6884514f5e3Sopenharmony_ci        EmitU8(0x74);
6894514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
6904514f5e3Sopenharmony_ci    } else {
6914514f5e3Sopenharmony_ci        if (target->IsLinked()) {
6924514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
6934514f5e3Sopenharmony_ci        }
6944514f5e3Sopenharmony_ci        // 2: skip opcode
6954514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
6964514f5e3Sopenharmony_ci        // 0F 84: Jz rel32
6974514f5e3Sopenharmony_ci        EmitU8(0X0F);
6984514f5e3Sopenharmony_ci        EmitU8(0x84);
6994514f5e3Sopenharmony_ci        EmitI32(emitPos);
7004514f5e3Sopenharmony_ci    }
7014514f5e3Sopenharmony_ci}
7024514f5e3Sopenharmony_ci
7034514f5e3Sopenharmony_civoid AssemblerX64::Je(Label *target, Distance distance)
7044514f5e3Sopenharmony_ci{
7054514f5e3Sopenharmony_ci    if (target->IsBound()) {
7064514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
7074514f5e3Sopenharmony_ci        EmitJe(offset);
7084514f5e3Sopenharmony_ci        return;
7094514f5e3Sopenharmony_ci    }
7104514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
7114514f5e3Sopenharmony_ci    int32_t emitPos = 0;
7124514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
7134514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
7144514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
7154514f5e3Sopenharmony_ci        }
7164514f5e3Sopenharmony_ci        // +1: skip opcode
7174514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
7184514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
7194514f5e3Sopenharmony_ci        // 74 : Je rel8
7204514f5e3Sopenharmony_ci        EmitU8(0x74);
7214514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
7224514f5e3Sopenharmony_ci    } else {
7234514f5e3Sopenharmony_ci        if (target->IsLinked()) {
7244514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
7254514f5e3Sopenharmony_ci        }
7264514f5e3Sopenharmony_ci        // 2: skip opcode
7274514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
7284514f5e3Sopenharmony_ci        // 0F 84: Je rel32
7294514f5e3Sopenharmony_ci        EmitU8(0X0F);
7304514f5e3Sopenharmony_ci        EmitU8(0x84);
7314514f5e3Sopenharmony_ci        EmitI32(emitPos);
7324514f5e3Sopenharmony_ci    }
7334514f5e3Sopenharmony_ci}
7344514f5e3Sopenharmony_ci
7354514f5e3Sopenharmony_civoid AssemblerX64::Bind(Label *target)
7364514f5e3Sopenharmony_ci{
7374514f5e3Sopenharmony_ci    size_t pos = GetCurrentPosition();
7384514f5e3Sopenharmony_ci    ASSERT(!target->IsBound());
7394514f5e3Sopenharmony_ci
7404514f5e3Sopenharmony_ci    if (target->IsLinked()) {
7414514f5e3Sopenharmony_ci        uint32_t linkPos = target->GetLinkedPos();
7424514f5e3Sopenharmony_ci        while (linkPos != 0) {
7434514f5e3Sopenharmony_ci            uint32_t preLinkPos = GetU32(linkPos);
7444514f5e3Sopenharmony_ci            int32_t disp = static_cast<int32_t>(pos - linkPos - sizeof(int32_t));
7454514f5e3Sopenharmony_ci            PutI32(linkPos, disp);
7464514f5e3Sopenharmony_ci            linkPos = preLinkPos;
7474514f5e3Sopenharmony_ci        }
7484514f5e3Sopenharmony_ci    }
7494514f5e3Sopenharmony_ci
7504514f5e3Sopenharmony_ci    if (target->IsLinkedNear()) {
7514514f5e3Sopenharmony_ci        uint32_t linkPos = target->GetLinkedNearPos();
7524514f5e3Sopenharmony_ci        while (linkPos != 0) {
7534514f5e3Sopenharmony_ci            int8_t offsetToNext = GetI8(static_cast<size_t>(linkPos));
7544514f5e3Sopenharmony_ci            int32_t disp = static_cast<int32_t>(pos - linkPos - sizeof(int8_t));
7554514f5e3Sopenharmony_ci            ASSERT(InRange8(disp));
7564514f5e3Sopenharmony_ci            PutI8(linkPos, static_cast<int8_t>(disp));
7574514f5e3Sopenharmony_ci            if (offsetToNext == 0) {
7584514f5e3Sopenharmony_ci                break;
7594514f5e3Sopenharmony_ci            }
7604514f5e3Sopenharmony_ci            linkPos += static_cast<uint32_t>(offsetToNext);
7614514f5e3Sopenharmony_ci        }
7624514f5e3Sopenharmony_ci        target->UnlinkNearPos();
7634514f5e3Sopenharmony_ci    }
7644514f5e3Sopenharmony_ci
7654514f5e3Sopenharmony_ci    target->BindTo(pos);
7664514f5e3Sopenharmony_ci}
7674514f5e3Sopenharmony_ci
7684514f5e3Sopenharmony_ciOperand::Operand(Register base, int32_t disp)
7694514f5e3Sopenharmony_ci{
7704514f5e3Sopenharmony_ci    if (base == rsp || base == r12) {
7714514f5e3Sopenharmony_ci        BuildSIB(Times1, rsp, base);
7724514f5e3Sopenharmony_ci    }
7734514f5e3Sopenharmony_ci    if (disp == 0 && base != rbp && base != r13) {
7744514f5e3Sopenharmony_ci        // 0: mode 00 [r/m]
7754514f5e3Sopenharmony_ci        BuildModerm(0, base);
7764514f5e3Sopenharmony_ci    } else if (AssemblerX64::InRange8(disp)) {
7774514f5e3Sopenharmony_ci        // 1: mode 01 [r/m + disp8]
7784514f5e3Sopenharmony_ci        BuildModerm(1, base);
7794514f5e3Sopenharmony_ci        BuildDisp8(disp);
7804514f5e3Sopenharmony_ci    } else {
7814514f5e3Sopenharmony_ci        // 2: mode 10 [r/m + disp32]
7824514f5e3Sopenharmony_ci        BuildModerm(2, base);
7834514f5e3Sopenharmony_ci        BuildDisp32(disp);
7844514f5e3Sopenharmony_ci    }
7854514f5e3Sopenharmony_ci}
7864514f5e3Sopenharmony_ci
7874514f5e3Sopenharmony_ciOperand::Operand(Register base, Register index, Scale scale, int32_t disp)
7884514f5e3Sopenharmony_ci{
7894514f5e3Sopenharmony_ci    BuildSIB(scale, index, base);
7904514f5e3Sopenharmony_ci    if (disp == 0 && base != rbp && base != r13) {
7914514f5e3Sopenharmony_ci        // 0: mode 00 [r/m]
7924514f5e3Sopenharmony_ci        BuildModerm(0, rsp);
7934514f5e3Sopenharmony_ci    } else if (AssemblerX64::InRange8(disp)) {
7944514f5e3Sopenharmony_ci        // 1: mode 01 [r/m + disp8]
7954514f5e3Sopenharmony_ci        BuildModerm(1, rsp);
7964514f5e3Sopenharmony_ci        BuildDisp8(disp);
7974514f5e3Sopenharmony_ci    } else {
7984514f5e3Sopenharmony_ci        // 2: mode 10 [r/m + disp32]
7994514f5e3Sopenharmony_ci        BuildModerm(2, rsp);
8004514f5e3Sopenharmony_ci        BuildDisp32(disp);
8014514f5e3Sopenharmony_ci    }
8024514f5e3Sopenharmony_ci}
8034514f5e3Sopenharmony_ci
8044514f5e3Sopenharmony_ci// [index * scale + disp]
8054514f5e3Sopenharmony_ciOperand::Operand(Register index, Scale scale, int32_t disp)
8064514f5e3Sopenharmony_ci{
8074514f5e3Sopenharmony_ci    ASSERT(index != rsp);
8084514f5e3Sopenharmony_ci    BuildModerm(0, rsp);
8094514f5e3Sopenharmony_ci    BuildSIB(scale, index, rbp);
8104514f5e3Sopenharmony_ci    BuildDisp32(disp);
8114514f5e3Sopenharmony_ci}
8124514f5e3Sopenharmony_ci
8134514f5e3Sopenharmony_civoid Operand::BuildSIB(Scale scale, Register index, Register base)
8144514f5e3Sopenharmony_ci{
8154514f5e3Sopenharmony_ci    sib_ = AssemblerX64::GetSIB(scale, index, base);
8164514f5e3Sopenharmony_ci    rex_ |= AssemblerX64::GetSIBRex(index, base);
8174514f5e3Sopenharmony_ci    hasSIB_ = true;
8184514f5e3Sopenharmony_ci}
8194514f5e3Sopenharmony_ci
8204514f5e3Sopenharmony_civoid Operand::BuildModerm(int32_t mode, Register rm)
8214514f5e3Sopenharmony_ci{
8224514f5e3Sopenharmony_ci    rex_ |= AssemblerX64::GetModrmRex(rm);
8234514f5e3Sopenharmony_ci    moderm_ = AssemblerX64::GetModrm(mode, rm);
8244514f5e3Sopenharmony_ci}
8254514f5e3Sopenharmony_ci
8264514f5e3Sopenharmony_civoid Operand::BuildDisp8(int32_t disp)
8274514f5e3Sopenharmony_ci{
8284514f5e3Sopenharmony_ci    disp_ = disp;
8294514f5e3Sopenharmony_ci    hasDisp8_ = true;
8304514f5e3Sopenharmony_ci}
8314514f5e3Sopenharmony_ci
8324514f5e3Sopenharmony_civoid Operand::BuildDisp32(int32_t disp)
8334514f5e3Sopenharmony_ci{
8344514f5e3Sopenharmony_ci    disp_ = disp;
8354514f5e3Sopenharmony_ci    hasDisp32_ = true;
8364514f5e3Sopenharmony_ci}
8374514f5e3Sopenharmony_ci
8384514f5e3Sopenharmony_civoid AssemblerX64::EmitOperand(int32_t reg, Operand rm)
8394514f5e3Sopenharmony_ci{
8404514f5e3Sopenharmony_ci    // moderm
8414514f5e3Sopenharmony_ci    EmitU8(rm.moderm_ | (static_cast<uint32_t>(reg) << LOW_BITS_SIZE));
8424514f5e3Sopenharmony_ci    if (rm.hasSIB_) {
8434514f5e3Sopenharmony_ci        EmitU8(rm.sib_);
8444514f5e3Sopenharmony_ci    }
8454514f5e3Sopenharmony_ci
8464514f5e3Sopenharmony_ci    if (rm.hasDisp8_) {
8474514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(rm.disp_));
8484514f5e3Sopenharmony_ci    } else if (rm.hasDisp32_) {
8494514f5e3Sopenharmony_ci        EmitI32(rm.disp_);
8504514f5e3Sopenharmony_ci    }
8514514f5e3Sopenharmony_ci}
8524514f5e3Sopenharmony_ci
8534514f5e3Sopenharmony_civoid AssemblerX64::Movl(Register src, Register dst)
8544514f5e3Sopenharmony_ci{
8554514f5e3Sopenharmony_ci    EmitRexPrefixl(src, dst);
8564514f5e3Sopenharmony_ci    // 0x89: Move r16 to r/m16
8574514f5e3Sopenharmony_ci    EmitU8(0x89);
8584514f5e3Sopenharmony_ci    EmitModrm(src, dst);
8594514f5e3Sopenharmony_ci}
8604514f5e3Sopenharmony_ci
8614514f5e3Sopenharmony_civoid AssemblerX64::Movl(const Operand &src, Register dst)
8624514f5e3Sopenharmony_ci{
8634514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
8644514f5e3Sopenharmony_ci    // 0x8B: Move r/m64 to r64
8654514f5e3Sopenharmony_ci    EmitU8(0x8B);
8664514f5e3Sopenharmony_ci    EmitOperand(dst, src);
8674514f5e3Sopenharmony_ci}
8684514f5e3Sopenharmony_ci
8694514f5e3Sopenharmony_civoid AssemblerX64::Movl(Register src, const Operand& dst)
8704514f5e3Sopenharmony_ci{
8714514f5e3Sopenharmony_ci    EmitRexPrefixl(src, dst);
8724514f5e3Sopenharmony_ci    // 0x89: Move r32 to r/m64
8734514f5e3Sopenharmony_ci    EmitU8(0x89);
8744514f5e3Sopenharmony_ci    EmitOperand(src, dst);
8754514f5e3Sopenharmony_ci}
8764514f5e3Sopenharmony_ci
8774514f5e3Sopenharmony_civoid AssemblerX64::Testq(Immediate src, Register dst)
8784514f5e3Sopenharmony_ci{
8794514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
8804514f5e3Sopenharmony_ci        Testb(src, dst);
8814514f5e3Sopenharmony_ci    } else if (dst == rax) {
8824514f5e3Sopenharmony_ci        // A9: Test rax, imm32
8834514f5e3Sopenharmony_ci        EmitU8(0xA9);
8844514f5e3Sopenharmony_ci        EmitI32(src.Value());
8854514f5e3Sopenharmony_ci    } else {
8864514f5e3Sopenharmony_ci        EmitRexPrefixW(dst);
8874514f5e3Sopenharmony_ci        // F7: Test r/m64, imm32
8884514f5e3Sopenharmony_ci        EmitU8(0xF7);
8894514f5e3Sopenharmony_ci        // 0: F7 0 id
8904514f5e3Sopenharmony_ci        EmitModrm(0, dst);
8914514f5e3Sopenharmony_ci        EmitI32(src.Value());
8924514f5e3Sopenharmony_ci    }
8934514f5e3Sopenharmony_ci}
8944514f5e3Sopenharmony_ci
8954514f5e3Sopenharmony_civoid AssemblerX64::Testb(Immediate src, Register dst)
8964514f5e3Sopenharmony_ci{
8974514f5e3Sopenharmony_ci    ASSERT(InRange8(src.Value()));
8984514f5e3Sopenharmony_ci    if (dst == rax) {
8994514f5e3Sopenharmony_ci        // A8: Test al, imm8
9004514f5e3Sopenharmony_ci        EmitU8(0xA8);
9014514f5e3Sopenharmony_ci    } else {
9024514f5e3Sopenharmony_ci        // AH BH CG DH can not be encoded to access if REX prefix used.
9034514f5e3Sopenharmony_ci        if (dst >= rsp) {
9044514f5e3Sopenharmony_ci            EmitRexPrefixL(dst);
9054514f5e3Sopenharmony_ci        }
9064514f5e3Sopenharmony_ci        // F6: Test r/m8, imm8
9074514f5e3Sopenharmony_ci        // REX F6: Test r/m8*, imm8
9084514f5e3Sopenharmony_ci        EmitU8(0xF6);
9094514f5e3Sopenharmony_ci        // 0: F6 /0 ib
9104514f5e3Sopenharmony_ci        EmitModrm(0, dst);
9114514f5e3Sopenharmony_ci    }
9124514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
9134514f5e3Sopenharmony_ci}
9144514f5e3Sopenharmony_ci
9154514f5e3Sopenharmony_civoid AssemblerX64::Jne(Label *target, Distance distance)
9164514f5e3Sopenharmony_ci{
9174514f5e3Sopenharmony_ci    if (target->IsBound()) {
9184514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
9194514f5e3Sopenharmony_ci        EmitJne(offset);
9204514f5e3Sopenharmony_ci        return;
9214514f5e3Sopenharmony_ci    }
9224514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
9234514f5e3Sopenharmony_ci    int32_t emitPos = 0;
9244514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
9254514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
9264514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
9274514f5e3Sopenharmony_ci        }
9284514f5e3Sopenharmony_ci        // +1: skip opcode
9294514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
9304514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
9314514f5e3Sopenharmony_ci        // 75 : Jne rel8;
9324514f5e3Sopenharmony_ci        EmitU8(0x75);
9334514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
9344514f5e3Sopenharmony_ci    } else {
9354514f5e3Sopenharmony_ci        if (target->IsLinked()) {
9364514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
9374514f5e3Sopenharmony_ci        }
9384514f5e3Sopenharmony_ci        // 2: skip opcode
9394514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
9404514f5e3Sopenharmony_ci        // 0F 85 : Jne rel32
9414514f5e3Sopenharmony_ci        EmitU8(0x0F);
9424514f5e3Sopenharmony_ci        EmitU8(0x85);
9434514f5e3Sopenharmony_ci        EmitI32(emitPos);
9444514f5e3Sopenharmony_ci    }
9454514f5e3Sopenharmony_ci}
9464514f5e3Sopenharmony_ci
9474514f5e3Sopenharmony_civoid AssemblerX64::Cmpl(Register src, Register dst)
9484514f5e3Sopenharmony_ci{
9494514f5e3Sopenharmony_ci    EmitRexPrefixl(src, dst);
9504514f5e3Sopenharmony_ci    // 39: Cmp r16 to r/m16
9514514f5e3Sopenharmony_ci    EmitU8(0x39);
9524514f5e3Sopenharmony_ci    EmitModrm(src, dst);
9534514f5e3Sopenharmony_ci}
9544514f5e3Sopenharmony_ci
9554514f5e3Sopenharmony_civoid AssemblerX64::Jbe(Label *target, Distance distance)
9564514f5e3Sopenharmony_ci{
9574514f5e3Sopenharmony_ci    if (target->IsBound()) {
9584514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
9594514f5e3Sopenharmony_ci        EmitJbe(offset);
9604514f5e3Sopenharmony_ci        return;
9614514f5e3Sopenharmony_ci    }
9624514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
9634514f5e3Sopenharmony_ci    int32_t emitPos = 0;
9644514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
9654514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
9664514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
9674514f5e3Sopenharmony_ci        }
9684514f5e3Sopenharmony_ci        // +1: skip opcode
9694514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
9704514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
9714514f5e3Sopenharmony_ci        // 76 : Jbe rel8;
9724514f5e3Sopenharmony_ci        EmitU8(0x76);
9734514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
9744514f5e3Sopenharmony_ci    } else {
9754514f5e3Sopenharmony_ci        if (target->IsLinked()) {
9764514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
9774514f5e3Sopenharmony_ci        }
9784514f5e3Sopenharmony_ci        // 2: skip opcode
9794514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
9804514f5e3Sopenharmony_ci        // 0F 86 : Jbe rel32
9814514f5e3Sopenharmony_ci        EmitU8(0x0F);
9824514f5e3Sopenharmony_ci        EmitU8(0x86);
9834514f5e3Sopenharmony_ci        EmitI32(emitPos);
9844514f5e3Sopenharmony_ci    }
9854514f5e3Sopenharmony_ci}
9864514f5e3Sopenharmony_ci
9874514f5e3Sopenharmony_civoid AssemblerX64::CMovbe(Register src, Register dst)
9884514f5e3Sopenharmony_ci{
9894514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
9904514f5e3Sopenharmony_ci    // 0f 46: CMovbe r32, r/m32
9914514f5e3Sopenharmony_ci    EmitU8(0x0F);
9924514f5e3Sopenharmony_ci    EmitU8(0x46);
9934514f5e3Sopenharmony_ci    EmitModrm(dst, src);
9944514f5e3Sopenharmony_ci}
9954514f5e3Sopenharmony_ci
9964514f5e3Sopenharmony_civoid AssemblerX64::Leaq(const Operand &src, Register dst)
9974514f5e3Sopenharmony_ci{
9984514f5e3Sopenharmony_ci    EmitRexPrefix(dst, src);
9994514f5e3Sopenharmony_ci    // 8D : lea r64, m
10004514f5e3Sopenharmony_ci    EmitU8(0x8D);
10014514f5e3Sopenharmony_ci    EmitOperand(dst, src);
10024514f5e3Sopenharmony_ci}
10034514f5e3Sopenharmony_ci
10044514f5e3Sopenharmony_civoid AssemblerX64::Leal(const Operand &src, Register dst)
10054514f5e3Sopenharmony_ci{
10064514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
10074514f5e3Sopenharmony_ci    // 8D : lea r64, m
10084514f5e3Sopenharmony_ci    EmitU8(0x8D);
10094514f5e3Sopenharmony_ci    EmitOperand(dst, src);
10104514f5e3Sopenharmony_ci}
10114514f5e3Sopenharmony_ci
10124514f5e3Sopenharmony_civoid AssemblerX64::Shrq(Immediate src, Register dst)
10134514f5e3Sopenharmony_ci{
10144514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
10154514f5e3Sopenharmony_ci    // C1 : Shr r/m64, imm8;
10164514f5e3Sopenharmony_ci    EmitU8(0xc1);
10174514f5e3Sopenharmony_ci    // 5: C1 /5 id
10184514f5e3Sopenharmony_ci    EmitModrm(5, dst);
10194514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
10204514f5e3Sopenharmony_ci}
10214514f5e3Sopenharmony_ci
10224514f5e3Sopenharmony_civoid AssemblerX64::Shrl(Immediate src, Register dst)
10234514f5e3Sopenharmony_ci{
10244514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
10254514f5e3Sopenharmony_ci    // C1 : Shr r/m32, imm8;
10264514f5e3Sopenharmony_ci    EmitU8(0xc1);
10274514f5e3Sopenharmony_ci    // 5: C1 /5 id
10284514f5e3Sopenharmony_ci    EmitModrm(5, dst);
10294514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
10304514f5e3Sopenharmony_ci}
10314514f5e3Sopenharmony_ci
10324514f5e3Sopenharmony_civoid AssemblerX64::Shr(Immediate src, Register dst)
10334514f5e3Sopenharmony_ci{
10344514f5e3Sopenharmony_ci    Shrq(src, dst);
10354514f5e3Sopenharmony_ci}
10364514f5e3Sopenharmony_ci
10374514f5e3Sopenharmony_civoid AssemblerX64::Andq(Immediate src, Register dst)
10384514f5e3Sopenharmony_ci{
10394514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
10404514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
10414514f5e3Sopenharmony_ci        // 83: and r/m64, imm8
10424514f5e3Sopenharmony_ci        EmitU8(0x83);
10434514f5e3Sopenharmony_ci        // 4: 83 /4 ib
10444514f5e3Sopenharmony_ci        EmitModrm(4, dst);
10454514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
10464514f5e3Sopenharmony_ci    } else if (dst == rax) {
10474514f5e3Sopenharmony_ci        // 0x25: and rax, imm32
10484514f5e3Sopenharmony_ci        EmitU8(0x25);
10494514f5e3Sopenharmony_ci        EmitI32(src.Value());
10504514f5e3Sopenharmony_ci    } else {
10514514f5e3Sopenharmony_ci        // 81: and r/m64, imm32
10524514f5e3Sopenharmony_ci        EmitU8(0x81);
10534514f5e3Sopenharmony_ci        // 4: 81 /4 id
10544514f5e3Sopenharmony_ci        EmitModrm(4, dst);
10554514f5e3Sopenharmony_ci        EmitI32(src.Value());
10564514f5e3Sopenharmony_ci    }
10574514f5e3Sopenharmony_ci}
10584514f5e3Sopenharmony_ci
10594514f5e3Sopenharmony_civoid AssemblerX64::Andl(Immediate src, Register dst)
10604514f5e3Sopenharmony_ci{
10614514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
10624514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
10634514f5e3Sopenharmony_ci        // 83: and r/m64, imm8
10644514f5e3Sopenharmony_ci        EmitU8(0x83);
10654514f5e3Sopenharmony_ci        // 4: 83 /4 ib
10664514f5e3Sopenharmony_ci        EmitModrm(4, dst);
10674514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
10684514f5e3Sopenharmony_ci    } else if (dst == rax) {
10694514f5e3Sopenharmony_ci        // 0x25: and rax, imm32
10704514f5e3Sopenharmony_ci        EmitU8(0x25);
10714514f5e3Sopenharmony_ci        EmitI32(src.Value());
10724514f5e3Sopenharmony_ci    } else {
10734514f5e3Sopenharmony_ci        // 81: and r/m64, imm32
10744514f5e3Sopenharmony_ci        EmitU8(0x81);
10754514f5e3Sopenharmony_ci        // 4: 81 /4 id
10764514f5e3Sopenharmony_ci        EmitModrm(4, dst);
10774514f5e3Sopenharmony_ci        EmitI32(src.Value());
10784514f5e3Sopenharmony_ci    }
10794514f5e3Sopenharmony_ci}
10804514f5e3Sopenharmony_ci
10814514f5e3Sopenharmony_civoid AssemblerX64::And(Register src, Register dst)
10824514f5e3Sopenharmony_ci{
10834514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
10844514f5e3Sopenharmony_ci    // 21 : And r/m64, r64
10854514f5e3Sopenharmony_ci    EmitU8(0x21);
10864514f5e3Sopenharmony_ci    EmitModrm(src, dst);
10874514f5e3Sopenharmony_ci}
10884514f5e3Sopenharmony_ci
10894514f5e3Sopenharmony_civoid AssemblerX64::Or(Immediate src, Register dst)
10904514f5e3Sopenharmony_ci{
10914514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
10924514f5e3Sopenharmony_ci    if (InRange8(src.Value())) {
10934514f5e3Sopenharmony_ci        // 83: or r/m64, imm8
10944514f5e3Sopenharmony_ci        EmitU8(0x83);
10954514f5e3Sopenharmony_ci        // 1: 83 /1 ib
10964514f5e3Sopenharmony_ci        EmitModrm(1, dst);
10974514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(src.Value()));
10984514f5e3Sopenharmony_ci    } else if (dst == rax) {
10994514f5e3Sopenharmony_ci        // 0x0D: or rax, imm32
11004514f5e3Sopenharmony_ci        EmitU8(0x0D);
11014514f5e3Sopenharmony_ci        EmitI32(src.Value());
11024514f5e3Sopenharmony_ci    } else {
11034514f5e3Sopenharmony_ci        // 81: or r/m64, imm32
11044514f5e3Sopenharmony_ci        EmitU8(0x81);
11054514f5e3Sopenharmony_ci        // 1: 81 /1 id
11064514f5e3Sopenharmony_ci        EmitModrm(1, dst);
11074514f5e3Sopenharmony_ci        EmitI32(src.Value());
11084514f5e3Sopenharmony_ci    }
11094514f5e3Sopenharmony_ci}
11104514f5e3Sopenharmony_ci
11114514f5e3Sopenharmony_civoid AssemblerX64::Orq(Register src, Register dst)
11124514f5e3Sopenharmony_ci{
11134514f5e3Sopenharmony_ci    EmitRexPrefix(src, dst);
11144514f5e3Sopenharmony_ci    // 09 : Or r/m64, r64
11154514f5e3Sopenharmony_ci    EmitU8(0x09);
11164514f5e3Sopenharmony_ci    EmitModrm(src, dst);
11174514f5e3Sopenharmony_ci}
11184514f5e3Sopenharmony_ci
11194514f5e3Sopenharmony_civoid AssemblerX64::Jnz(Label *target, Distance distance)
11204514f5e3Sopenharmony_ci{
11214514f5e3Sopenharmony_ci    if (target->IsBound()) {
11224514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
11234514f5e3Sopenharmony_ci        EmitJnz(offset);
11244514f5e3Sopenharmony_ci        return;
11254514f5e3Sopenharmony_ci    }
11264514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
11274514f5e3Sopenharmony_ci    int32_t emitPos = 0;
11284514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
11294514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
11304514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
11314514f5e3Sopenharmony_ci        }
11324514f5e3Sopenharmony_ci        // +1: skip opcode
11334514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
11344514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
11354514f5e3Sopenharmony_ci        // 75 : Jnz rel8;
11364514f5e3Sopenharmony_ci        EmitU8(0x75);
11374514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
11384514f5e3Sopenharmony_ci    } else {
11394514f5e3Sopenharmony_ci        if (target->IsLinked()) {
11404514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
11414514f5e3Sopenharmony_ci        }
11424514f5e3Sopenharmony_ci        // 2: skip opcode
11434514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
11444514f5e3Sopenharmony_ci        // 0F 85 : Jnz rel32
11454514f5e3Sopenharmony_ci        EmitU8(0x0F);
11464514f5e3Sopenharmony_ci        EmitU8(0x85);
11474514f5e3Sopenharmony_ci        EmitI32(emitPos);
11484514f5e3Sopenharmony_ci    }
11494514f5e3Sopenharmony_ci}
11504514f5e3Sopenharmony_ci
11514514f5e3Sopenharmony_civoid AssemblerX64::Jle(Label *target, Distance distance)
11524514f5e3Sopenharmony_ci{
11534514f5e3Sopenharmony_ci    if (target->IsBound()) {
11544514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
11554514f5e3Sopenharmony_ci        EmitJle(offset);
11564514f5e3Sopenharmony_ci        return;
11574514f5e3Sopenharmony_ci    }
11584514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
11594514f5e3Sopenharmony_ci    int32_t emitPos = 0;
11604514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
11614514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
11624514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
11634514f5e3Sopenharmony_ci        }
11644514f5e3Sopenharmony_ci        // +1: skip opcode
11654514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
11664514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
11674514f5e3Sopenharmony_ci        // 7E : Jle rel8;
11684514f5e3Sopenharmony_ci        EmitU8(0x7E);
11694514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
11704514f5e3Sopenharmony_ci    } else {
11714514f5e3Sopenharmony_ci        if (target->IsLinked()) {
11724514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
11734514f5e3Sopenharmony_ci        }
11744514f5e3Sopenharmony_ci        // 2: skip opcode
11754514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
11764514f5e3Sopenharmony_ci        // 0F 8E: Jle rel32
11774514f5e3Sopenharmony_ci        EmitU8(0x0F);
11784514f5e3Sopenharmony_ci        EmitU8(0x8E);
11794514f5e3Sopenharmony_ci        EmitI32(emitPos);
11804514f5e3Sopenharmony_ci    }
11814514f5e3Sopenharmony_ci}
11824514f5e3Sopenharmony_ci
11834514f5e3Sopenharmony_civoid AssemblerX64::Jae(Label *target, Distance distance)
11844514f5e3Sopenharmony_ci{
11854514f5e3Sopenharmony_ci    if (target->IsBound()) {
11864514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
11874514f5e3Sopenharmony_ci        EmitJae(offset);
11884514f5e3Sopenharmony_ci        return;
11894514f5e3Sopenharmony_ci    }
11904514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
11914514f5e3Sopenharmony_ci    int32_t emitPos = 0;
11924514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
11934514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
11944514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
11954514f5e3Sopenharmony_ci        }
11964514f5e3Sopenharmony_ci        // +1: skip opcode
11974514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
11984514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
11994514f5e3Sopenharmony_ci        // 73 : Jae rel8
12004514f5e3Sopenharmony_ci        EmitU8(0x73);
12014514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
12024514f5e3Sopenharmony_ci    } else {
12034514f5e3Sopenharmony_ci        if (target->IsLinked()) {
12044514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
12054514f5e3Sopenharmony_ci        }
12064514f5e3Sopenharmony_ci        // 2: skip opcode
12074514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
12084514f5e3Sopenharmony_ci        // 0F 83: Jae rel32
12094514f5e3Sopenharmony_ci        EmitU8(0x0F);
12104514f5e3Sopenharmony_ci        EmitU8(0x83);
12114514f5e3Sopenharmony_ci        EmitI32(emitPos);
12124514f5e3Sopenharmony_ci    }
12134514f5e3Sopenharmony_ci}
12144514f5e3Sopenharmony_ci
12154514f5e3Sopenharmony_civoid AssemblerX64::Jg(Label *target, Distance distance)
12164514f5e3Sopenharmony_ci{
12174514f5e3Sopenharmony_ci    if (target->IsBound()) {
12184514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
12194514f5e3Sopenharmony_ci        EmitJg(offset);
12204514f5e3Sopenharmony_ci        return;
12214514f5e3Sopenharmony_ci    }
12224514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
12234514f5e3Sopenharmony_ci    int32_t emitPos = 0;
12244514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
12254514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
12264514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
12274514f5e3Sopenharmony_ci        }
12284514f5e3Sopenharmony_ci        // +1: skip opcode
12294514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
12304514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
12314514f5e3Sopenharmony_ci        // 7F : Jg rel8
12324514f5e3Sopenharmony_ci        EmitU8(0x7F);
12334514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
12344514f5e3Sopenharmony_ci    } else {
12354514f5e3Sopenharmony_ci        if (target->IsLinked()) {
12364514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
12374514f5e3Sopenharmony_ci        }
12384514f5e3Sopenharmony_ci        // 2: skip opcode
12394514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
12404514f5e3Sopenharmony_ci        // 0F 8F: Jae rel32
12414514f5e3Sopenharmony_ci        EmitU8(0x0F);
12424514f5e3Sopenharmony_ci        EmitU8(0x8F);
12434514f5e3Sopenharmony_ci        EmitI32(emitPos);
12444514f5e3Sopenharmony_ci    }
12454514f5e3Sopenharmony_ci}
12464514f5e3Sopenharmony_ci
12474514f5e3Sopenharmony_civoid AssemblerX64::Jge(Label *target, Distance distance)
12484514f5e3Sopenharmony_ci{
12494514f5e3Sopenharmony_ci    if (target->IsBound()) {
12504514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
12514514f5e3Sopenharmony_ci        EmitJge(offset);
12524514f5e3Sopenharmony_ci        return;
12534514f5e3Sopenharmony_ci    }
12544514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
12554514f5e3Sopenharmony_ci    int32_t emitPos = 0;
12564514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
12574514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
12584514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
12594514f5e3Sopenharmony_ci        }
12604514f5e3Sopenharmony_ci        // +1: skip opcode
12614514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
12624514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
12634514f5e3Sopenharmony_ci        // 7F : Jg rel8
12644514f5e3Sopenharmony_ci        EmitU8(0x7D);
12654514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
12664514f5e3Sopenharmony_ci    } else {
12674514f5e3Sopenharmony_ci        if (target->IsLinked()) {
12684514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
12694514f5e3Sopenharmony_ci        }
12704514f5e3Sopenharmony_ci        // 2: skip opcode
12714514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
12724514f5e3Sopenharmony_ci        // 0F 8F: Jae rel32
12734514f5e3Sopenharmony_ci        EmitU8(0x0F);
12744514f5e3Sopenharmony_ci        EmitU8(0x8D);
12754514f5e3Sopenharmony_ci        EmitI32(emitPos);
12764514f5e3Sopenharmony_ci    }
12774514f5e3Sopenharmony_ci}
12784514f5e3Sopenharmony_ci
12794514f5e3Sopenharmony_civoid AssemblerX64::Movzbq(const Operand &src, Register dst)
12804514f5e3Sopenharmony_ci{
12814514f5e3Sopenharmony_ci    EmitRexPrefix(dst, src);
12824514f5e3Sopenharmony_ci    // 0F B6 : Movzx r64, r/m16
12834514f5e3Sopenharmony_ci    EmitU8(0x0F);
12844514f5e3Sopenharmony_ci    EmitU8(0xB6);
12854514f5e3Sopenharmony_ci    // 0F B6 /r: Movzx r64, r/m16
12864514f5e3Sopenharmony_ci    EmitOperand(dst, src);
12874514f5e3Sopenharmony_ci}
12884514f5e3Sopenharmony_ci
12894514f5e3Sopenharmony_civoid AssemblerX64::Movzbl(const Operand &src, Register dst)
12904514f5e3Sopenharmony_ci{
12914514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
12924514f5e3Sopenharmony_ci    // 0F B6 : Movzx r64, r/m16
12934514f5e3Sopenharmony_ci    EmitU8(0x0F);
12944514f5e3Sopenharmony_ci    EmitU8(0xB6);
12954514f5e3Sopenharmony_ci    // 0F B6 /r: Movzx r64, r/m16
12964514f5e3Sopenharmony_ci    EmitOperand(dst, src);
12974514f5e3Sopenharmony_ci}
12984514f5e3Sopenharmony_ci
12994514f5e3Sopenharmony_civoid AssemblerX64::Movzbl(Register src, Register dst)
13004514f5e3Sopenharmony_ci{
13014514f5e3Sopenharmony_ci    EmitRexPrefixl(dst, src);
13024514f5e3Sopenharmony_ci    // 0F B6 : Movzx r64, r/m16
13034514f5e3Sopenharmony_ci    EmitU8(0x0F);
13044514f5e3Sopenharmony_ci    EmitU8(0xB6);
13054514f5e3Sopenharmony_ci    // 0F B6 /r: Movzx r64, r/m16
13064514f5e3Sopenharmony_ci    EmitModrm(dst, src);
13074514f5e3Sopenharmony_ci}
13084514f5e3Sopenharmony_ci
13094514f5e3Sopenharmony_civoid AssemblerX64::Btq(Immediate src, Register dst)
13104514f5e3Sopenharmony_ci{
13114514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
13124514f5e3Sopenharmony_ci    // 0F BA: bt r/m32, imm8;
13134514f5e3Sopenharmony_ci    EmitU8(0x0F);
13144514f5e3Sopenharmony_ci    EmitU8(0xBA);
13154514f5e3Sopenharmony_ci    // /4: 0F BA bt r/m32, imm8
13164514f5e3Sopenharmony_ci    EmitModrm(4, dst);
13174514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
13184514f5e3Sopenharmony_ci}
13194514f5e3Sopenharmony_civoid AssemblerX64::Btl(Immediate src, Register dst)
13204514f5e3Sopenharmony_ci{
13214514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
13224514f5e3Sopenharmony_ci    // 0F BA: bt r/m32, imm8;
13234514f5e3Sopenharmony_ci    EmitU8(0x0F);
13244514f5e3Sopenharmony_ci    EmitU8(0xBA);
13254514f5e3Sopenharmony_ci    // /4: 0F BA bt r/m32, imm8
13264514f5e3Sopenharmony_ci    EmitModrm(4, dst);
13274514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
13284514f5e3Sopenharmony_ci}
13294514f5e3Sopenharmony_ci
13304514f5e3Sopenharmony_civoid AssemblerX64::Movabs(uint64_t src, Register dst)
13314514f5e3Sopenharmony_ci{
13324514f5e3Sopenharmony_ci    // REX.W + B8 + rd io : Mov r64, imm64
13334514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
13344514f5e3Sopenharmony_ci    EmitU8(0xB8 | LowBits(dst));
13354514f5e3Sopenharmony_ci    EmitU64(src);
13364514f5e3Sopenharmony_ci}
13374514f5e3Sopenharmony_ci
13384514f5e3Sopenharmony_civoid AssemblerX64::Shll(Immediate src, Register dst)
13394514f5e3Sopenharmony_ci{
13404514f5e3Sopenharmony_ci    EmitRexPrefix(dst);
13414514f5e3Sopenharmony_ci    // C1 : shl r/m32, imm8
13424514f5e3Sopenharmony_ci    EmitU8(0xC1);
13434514f5e3Sopenharmony_ci    // C1 /4
13444514f5e3Sopenharmony_ci    EmitModrm(4, dst);
13454514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
13464514f5e3Sopenharmony_ci}
13474514f5e3Sopenharmony_ci
13484514f5e3Sopenharmony_civoid AssemblerX64::Shlq(Immediate src, Register dst)
13494514f5e3Sopenharmony_ci{
13504514f5e3Sopenharmony_ci    EmitRexPrefixW(dst);
13514514f5e3Sopenharmony_ci    // C1 : shl r/m64, imm8
13524514f5e3Sopenharmony_ci    EmitU8(0xC1);
13534514f5e3Sopenharmony_ci    // C1 /4
13544514f5e3Sopenharmony_ci    EmitModrm(4, dst);
13554514f5e3Sopenharmony_ci    EmitI8(static_cast<int8_t>(src.Value()));
13564514f5e3Sopenharmony_ci}
13574514f5e3Sopenharmony_ci
13584514f5e3Sopenharmony_civoid AssemblerX64::Btsl(Register src, Register dst)
13594514f5e3Sopenharmony_ci{
13604514f5e3Sopenharmony_ci    EmitRexPrefixl(src, dst);
13614514f5e3Sopenharmony_ci    // 0F AB: bts r32, r32;
13624514f5e3Sopenharmony_ci    EmitU8(0x0F);
13634514f5e3Sopenharmony_ci    EmitU8(0xAB);
13644514f5e3Sopenharmony_ci
13654514f5e3Sopenharmony_ci    EmitModrm(src, dst);
13664514f5e3Sopenharmony_ci}
13674514f5e3Sopenharmony_ci
13684514f5e3Sopenharmony_civoid AssemblerX64::Int3()
13694514f5e3Sopenharmony_ci{
13704514f5e3Sopenharmony_ci    // CC :: INT3
13714514f5e3Sopenharmony_ci    EmitU8(0xCC);
13724514f5e3Sopenharmony_ci}
13734514f5e3Sopenharmony_ci
13744514f5e3Sopenharmony_civoid AssemblerX64::Movzwq(const Operand &src, Register dst)
13754514f5e3Sopenharmony_ci{
13764514f5e3Sopenharmony_ci    EmitRexPrefix(dst, src);
13774514f5e3Sopenharmony_ci    EmitU8(0x0F);
13784514f5e3Sopenharmony_ci    EmitU8(0xB7);
13794514f5e3Sopenharmony_ci    EmitOperand(dst, src);
13804514f5e3Sopenharmony_ci}
13814514f5e3Sopenharmony_ci
13824514f5e3Sopenharmony_civoid AssemblerX64::Jnb(Label *target, Distance distance)
13834514f5e3Sopenharmony_ci{
13844514f5e3Sopenharmony_ci    if (target->IsBound()) {
13854514f5e3Sopenharmony_ci        int32_t offset = static_cast<int32_t>(target->GetPos() - GetCurrentPosition());
13864514f5e3Sopenharmony_ci        EmitJnb(offset);
13874514f5e3Sopenharmony_ci        return;
13884514f5e3Sopenharmony_ci    }
13894514f5e3Sopenharmony_ci    auto pos = GetCurrentPosition();
13904514f5e3Sopenharmony_ci    int32_t emitPos = 0;
13914514f5e3Sopenharmony_ci    if (distance == Distance::Near) {
13924514f5e3Sopenharmony_ci        if (target->IsLinkedNear()) {
13934514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedNearPos() - pos);
13944514f5e3Sopenharmony_ci        }
13954514f5e3Sopenharmony_ci        // +1: skip opcode
13964514f5e3Sopenharmony_ci        target->LinkNearPos(pos + 1);
13974514f5e3Sopenharmony_ci        ASSERT(InRange8(emitPos));
13984514f5e3Sopenharmony_ci        // 73 : Jnb rel8
13994514f5e3Sopenharmony_ci        EmitU8(0x73);
14004514f5e3Sopenharmony_ci        EmitI8(static_cast<int8_t>(emitPos));
14014514f5e3Sopenharmony_ci    } else {
14024514f5e3Sopenharmony_ci        if (target->IsLinked()) {
14034514f5e3Sopenharmony_ci            emitPos = static_cast<int32_t>(target->GetLinkedPos());
14044514f5e3Sopenharmony_ci        }
14054514f5e3Sopenharmony_ci        // 2: skip opcode
14064514f5e3Sopenharmony_ci        target->LinkTo(pos + 2);
14074514f5e3Sopenharmony_ci        // 0F 83: Jnb rel32
14084514f5e3Sopenharmony_ci        EmitU8(0x0F);
14094514f5e3Sopenharmony_ci        EmitU8(0x83);
14104514f5e3Sopenharmony_ci        EmitI32(emitPos);
14114514f5e3Sopenharmony_ci    }
14124514f5e3Sopenharmony_ci}
14134514f5e3Sopenharmony_ci}  // panda::ecmascript::x64
1414