// SPDX-License-Identifier: Zlib
#ifndef DFLTCC_UTIL_H
#define DFLTCC_UTIL_H

#include "dfltcc.h"
#include <linux/kmsan-checks.h>
#include <linux/zutil.h>

/*
 * C wrapper for the DEFLATE CONVERSION CALL instruction.
 */
typedef enum {
    DFLTCC_CC_OK = 0,
    DFLTCC_CC_OP1_TOO_SHORT = 1,
    DFLTCC_CC_OP2_TOO_SHORT = 2,
    DFLTCC_CC_OP2_CORRUPT = 2,
    DFLTCC_CC_AGAIN = 3,
} dfltcc_cc;

#define DFLTCC_QAF 0
#define DFLTCC_GDHT 1
#define DFLTCC_CMPR 2
#define DFLTCC_XPND 4
#define HBT_CIRCULAR (1 << 7)
#define DFLTCC_FN_MASK ((1 << 7) - 1)
#define HB_BITS 15
#define HB_SIZE (1 << HB_BITS)

static inline dfltcc_cc dfltcc(
    int fn,
    void *param,
    Byte **op1,
    size_t *len1,
    const Byte **op2,
    size_t *len2,
    void *hist
)
{
    Byte *t2 = op1 ? *op1 : NULL;
    unsigned char *orig_t2 = t2;
    size_t t3 = len1 ? *len1 : 0;
    const Byte *t4 = op2 ? *op2 : NULL;
    size_t t5 = len2 ? *len2 : 0;
    register int r0 __asm__("r0") = fn;
    register void *r1 __asm__("r1") = param;
    register Byte *r2 __asm__("r2") = t2;
    register size_t r3 __asm__("r3") = t3;
    register const Byte *r4 __asm__("r4") = t4;
    register size_t r5 __asm__("r5") = t5;
    int cc;

    __asm__ volatile(
                     ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
                     "ipm %[cc]\n"
                     : [r2] "+r" (r2)
                     , [r3] "+r" (r3)
                     , [r4] "+r" (r4)
                     , [r5] "+r" (r5)
                     , [cc] "=r" (cc)
                     : [r0] "r" (r0)
                     , [r1] "r" (r1)
                     , [hist] "r" (hist)
                     : "cc", "memory");
    t2 = r2; t3 = r3; t4 = r4; t5 = r5;

    /*
     * Unpoison the parameter block and the output buffer.
     * This is a no-op in non-KMSAN builds.
     */
    switch (fn & DFLTCC_FN_MASK) {
    case DFLTCC_QAF:
        kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));
        break;
    case DFLTCC_GDHT:
        kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));
        break;
    case DFLTCC_CMPR:
        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
        kmsan_unpoison_memory(
                orig_t2,
                t2 - orig_t2 +
                    (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
        break;
    case DFLTCC_XPND:
        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
        kmsan_unpoison_memory(orig_t2, t2 - orig_t2);
        break;
    }

    if (op1)
        *op1 = t2;
    if (len1)
        *len1 = t3;
    if (op2)
        *op2 = t4;
    if (len2)
        *len2 = t5;
    return (cc >> 28) & 3;
}

static inline int is_bit_set(
    const char *bits,
    int n
)
{
    return bits[n / 8] & (1 << (7 - (n % 8)));
}

static inline void turn_bit_off(
    char *bits,
    int n
)
{
    bits[n / 8] &= ~(1 << (7 - (n % 8)));
}

static inline int dfltcc_are_params_ok(
    int level,
    uInt window_bits,
    int strategy,
    uLong level_mask
)
{
    return (level_mask & (1 << level)) != 0 &&
        (window_bits == HB_BITS) &&
        (strategy == Z_DEFAULT_STRATEGY);
}

char *oesc_msg(char *buf, int oesc);

#endif /* DFLTCC_UTIL_H */
