^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: Zlib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef DFLTCC_UTIL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define DFLTCC_UTIL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/zutil.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * C wrapper for the DEFLATE CONVERSION CALL instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) typedef enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) DFLTCC_CC_OK = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) DFLTCC_CC_OP1_TOO_SHORT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) DFLTCC_CC_OP2_TOO_SHORT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) DFLTCC_CC_OP2_CORRUPT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) DFLTCC_CC_AGAIN = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) } dfltcc_cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define DFLTCC_QAF 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define DFLTCC_GDHT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define DFLTCC_CMPR 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DFLTCC_XPND 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define HBT_CIRCULAR (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define HB_BITS 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define HB_SIZE (1 << HB_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline dfltcc_cc dfltcc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) Byte **op1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) size_t *len1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const Byte **op2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) size_t *len2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) void *hist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) Byte *t2 = op1 ? *op1 : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) size_t t3 = len1 ? *len1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) const Byte *t4 = op2 ? *op2 : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) size_t t5 = len2 ? *len2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) register int r0 __asm__("r0") = fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) register void *r1 __asm__("r1") = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) register Byte *r2 __asm__("r2") = t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) register size_t r3 __asm__("r3") = t3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) register const Byte *r4 __asm__("r4") = t4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) register size_t r5 __asm__("r5") = t5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) __asm__ volatile(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "ipm %[cc]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) : [r2] "+r" (r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) , [r3] "+r" (r3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) , [r4] "+r" (r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) , [r5] "+r" (r5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) , [cc] "=r" (cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) : [r0] "r" (r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) , [r1] "r" (r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) , [hist] "r" (hist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) t2 = r2; t3 = r3; t4 = r4; t5 = r5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (op1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) *op1 = t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (len1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *len1 = t3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (op2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *op2 = t4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (len2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *len2 = t5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return (cc >> 28) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline int is_bit_set(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) const char *bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return bits[n / 8] & (1 << (7 - (n % 8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static inline void turn_bit_off(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) char *bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bits[n / 8] &= ~(1 << (7 - (n % 8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static inline int dfltcc_are_params_ok(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) uInt window_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int strategy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) uLong level_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return (level_mask & (1 << level)) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (window_bits == HB_BITS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) (strategy == Z_DEFAULT_STRATEGY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) char *oesc_msg(char *buf, int oesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #endif /* DFLTCC_UTIL_H */