// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause // Wide-immediate arithmetic: every classification band of the ADD/SUB // immediate family (single imm12, the ADDCON2 split, bitmask and MOVZ/MOVN/ // MOVK materialisations into REGTMP) plus the logical bitmask immediates and // their materialised fallback. Byte-for-byte against go tool asm. #include "textflag.h" // imm12 covers the plain and shifted-by-12 imm12 forms. TEXT ·imm12(SB), NOSPLIT, $0-0 ADD $1, R2, R3 ADD $0x000aaa, R2, R3 ADD $0xaaa000, R2 SUB $0x000aaa, R2, R3 SUB $0xaaa000, R2 ADDW $40960, R0 CMP $40960, R0 CMPW $40960, R0 RET // split pins the ADDCON2 band: two imm12 instructions, low half first. TEXT ·split(SB), NOSPLIT, $0-0 ADD $0xaaaaaa, R2, R3 SUB $0xaaaaaa, R2 ADD $0x186a0, R2, R5 SUB $0x186a0, R2, R3 ADDW $0x60060, R2 RET // regtmp covers the single-word materialisations: MOVZ for a movcon value, // MOVN for the complement form, the bitmask ORR otherwise. TEXT ·regtmp(SB), NOSPLIT, $0-0 ADD $0x1ffe00, R2, R3 ADD $0x3fffffffc000, R5 ADD $-2048, R2, R3 ADD $-100000, R2, R3 CMP $0x1000000, R2 CMP $0x100000000, R0 SUB $-0x100000000, R0, R1 RET // movseq covers the omovlconst sequences: MOVZ/MOVN ladders and the // compare forms that never split. TEXT ·movseq(SB), NOSPLIT, $0-0 ADD $0x12345678, R2, R3 SUB $0xe7791f700, R3, R1 CMP $0xaaaaaa, R2 CMP $0xffffffffffa0, R3 CMPW $27745, R2 CMPW $0x60060, R2 ADDS $0xaaaaaa, R2, R3 CMN $0x1000000, R2 ADDW $0x12345678, R2, R3 RET // logical covers the bitmask immediates of the logical family and the // materialised fallback for the values a bitmask cannot carry. TEXT ·logical(SB), NOSPLIT, $0-0 AND $0x3ff00000, R2, R3 BIC $0x22220000, R3, R4 ORR $0x3ff00000, R2 EOR $0x3ff00000, R2, R3 ANDS $0x3ff00000, R2 ORNW $0x3ff00000, R2 EONW $0x3ff00000, R2 BICSW $0x6006000060060, R5 TST $0x4900000049, R0 RET