863 * 864 * @param reg general purpose register. May not be null, zero-register or stackpointer. 865 * @param uimm6 Unsigned 6-bit bit index. 866 * @param imm16 signed 16 bit offset 867 */ 868 protected void tbz(Register reg, int uimm6, int imm16) { 869 tbz(reg, uimm6, imm16, -1); 870 } 871 872 /** 873 * Test a single bit and branch if the bit is nonzero. 874 * 875 * @param reg general purpose register. May not be null, zero-register or stackpointer. 876 * @param uimm6 Unsigned 6-bit bit index. 877 * @param imm16 signed 16 bit offset 878 * @param pos Position at which instruction is inserted into buffer. -1 means insert at end. 879 */ 880 protected void tbnz(Register reg, int uimm6, int imm16, int pos) { 881 assert reg.getRegisterCategory().equals(CPU); 882 assert NumUtil.isUnsignedNbit(6, uimm6); 883 assert NumUtil.isSignedNbit(18, imm16); 884 assert (imm16 & 3) == 0; 885 // size bit is overloaded as top bit of uimm6 bit index 886 int size = (((uimm6 >> 5) & 1) == 0 ? 32 : 64); 887 // remaining 5 bits are encoded lower down 888 int uimm5 = uimm6 >> 1; 889 int offset = (imm16 & NumUtil.getNbitNumberInt(16)) >> 2; 890 InstructionType type = generalFromSize(size); 891 int encoding = type.encoding | TBNZ.encoding | (uimm5 << 19) | (offset << 5) | rd(reg); 892 if (pos == -1) { 893 emitInt(encoding); 894 } else { 895 emitInt(encoding, pos); 896 } 897 } 898 899 /** 900 * Test a single bit and branch if the bit is zero. 901 * 902 * @param reg general purpose register. May not be null, zero-register or stackpointer. 903 * @param uimm6 Unsigned 6-bit bit index. 904 * @param imm16 signed 16 bit offset 905 * @param pos Position at which instruction is inserted into buffer. -1 means insert at end. 906 */ 907 protected void tbz(Register reg, int uimm6, int imm16, int pos) { 908 assert reg.getRegisterCategory().equals(CPU); 909 assert NumUtil.isUnsignedNbit(6, uimm6); 910 assert NumUtil.isSignedNbit(18, imm16); 911 assert (imm16 & 3) == 0; 912 // size bit is overloaded as top bit of uimm6 bit index 913 int size = (((uimm6 >> 5) & 1) == 0 ? 32 : 64); 914 // remaining 5 bits are encoded lower down 915 int uimm5 = uimm6 >> 1; 916 int offset = (imm16 & NumUtil.getNbitNumberInt(16)) >> 2; 917 InstructionType type = generalFromSize(size); 918 int encoding = type.encoding | TBZ.encoding | (uimm5 << 19) | (offset << 5) | rd(reg); 919 if (pos == -1) { 920 emitInt(encoding); 921 } else { 922 emitInt(encoding, pos); 923 } 924 } 925 926 private void conditionalBranchInstruction(Register reg, int imm21, InstructionType type, Instruction instr, int pos) { 927 assert reg.getRegisterCategory().equals(CPU); 928 int instrEncoding = instr.encoding | CompareBranchOp; 929 if (pos == -1) { 930 emitInt(type.encoding | instrEncoding | getConditionalBranchImm(imm21) | rd(reg)); 931 } else { 932 emitInt(type.encoding | instrEncoding | getConditionalBranchImm(imm21) | rd(reg), pos); 933 } 934 } 935 936 private static int getConditionalBranchImm(int imm21) { 937 assert NumUtil.isSignedNbit(21, imm21) && (imm21 & 0x3) == 0 : "Immediate has to be 21bit signed number and word aligned"; 938 int imm = (imm21 & NumUtil.getNbitNumberInt(21)) >> 2; | 863 * 864 * @param reg general purpose register. May not be null, zero-register or stackpointer. 865 * @param uimm6 Unsigned 6-bit bit index. 866 * @param imm16 signed 16 bit offset 867 */ 868 protected void tbz(Register reg, int uimm6, int imm16) { 869 tbz(reg, uimm6, imm16, -1); 870 } 871 872 /** 873 * Test a single bit and branch if the bit is nonzero. 874 * 875 * @param reg general purpose register. May not be null, zero-register or stackpointer. 876 * @param uimm6 Unsigned 6-bit bit index. 877 * @param imm16 signed 16 bit offset 878 * @param pos Position at which instruction is inserted into buffer. -1 means insert at end. 879 */ 880 protected void tbnz(Register reg, int uimm6, int imm16, int pos) { 881 assert reg.getRegisterCategory().equals(CPU); 882 assert NumUtil.isUnsignedNbit(6, uimm6); 883 assert NumUtil.isSignedNbit(16, imm16) : String.format("Offset value must fit in 16 bits signed: 0x%x", imm16); 884 assert (imm16 & 3) == 0 : String.format("Lower two bits must be zero: 0x%x", imm16 & 3); 885 // size bit is overloaded as top bit of uimm6 bit index 886 int size = (((uimm6 >> 5) & 1) == 0 ? 32 : 64); 887 // remaining 5 bits are encoded lower down 888 int uimm5 = uimm6 & 0x1F; 889 int imm14 = (imm16 & NumUtil.getNbitNumberInt(16)) >> 2; 890 InstructionType type = generalFromSize(size); 891 int encoding = type.encoding | TBNZ.encoding | (uimm5 << 19) | (imm14 << 5) | rd(reg); 892 if (pos == -1) { 893 emitInt(encoding); 894 } else { 895 emitInt(encoding, pos); 896 } 897 } 898 899 /** 900 * Test a single bit and branch if the bit is zero. 901 * 902 * @param reg general purpose register. May not be null, zero-register or stackpointer. 903 * @param uimm6 Unsigned 6-bit bit index. 904 * @param imm16 signed 16 bit offset 905 * @param pos Position at which instruction is inserted into buffer. -1 means insert at end. 906 */ 907 protected void tbz(Register reg, int uimm6, int imm16, int pos) { 908 assert reg.getRegisterCategory().equals(CPU); 909 assert NumUtil.isUnsignedNbit(6, uimm6); 910 assert NumUtil.isSignedNbit(16, imm16) : String.format("Offset value must fit in 16 bits signed: 0x%x", imm16); 911 assert (imm16 & 3) == 0 : String.format("Lower two bits must be zero: 0x%x", imm16 & 3); 912 // size bit is overloaded as top bit of uimm6 bit index 913 int size = (((uimm6 >> 5) & 1) == 0 ? 32 : 64); 914 // remaining 5 bits are encoded lower down 915 int uimm5 = uimm6 & 0x1F; 916 int imm14 = (imm16 & NumUtil.getNbitNumberInt(16)) >> 2; 917 InstructionType type = generalFromSize(size); 918 int encoding = type.encoding | TBZ.encoding | (uimm5 << 19) | (imm14 << 5) | rd(reg); 919 if (pos == -1) { 920 emitInt(encoding); 921 } else { 922 emitInt(encoding, pos); 923 } 924 } 925 926 private void conditionalBranchInstruction(Register reg, int imm21, InstructionType type, Instruction instr, int pos) { 927 assert reg.getRegisterCategory().equals(CPU); 928 int instrEncoding = instr.encoding | CompareBranchOp; 929 if (pos == -1) { 930 emitInt(type.encoding | instrEncoding | getConditionalBranchImm(imm21) | rd(reg)); 931 } else { 932 emitInt(type.encoding | instrEncoding | getConditionalBranchImm(imm21) | rd(reg), pos); 933 } 934 } 935 936 private static int getConditionalBranchImm(int imm21) { 937 assert NumUtil.isSignedNbit(21, imm21) && (imm21 & 0x3) == 0 : "Immediate has to be 21bit signed number and word aligned"; 938 int imm = (imm21 & NumUtil.getNbitNumberInt(21)) >> 2; |