diff --git a/firmware/common/u128.c b/firmware/common/u128.c new file mode 100644 index 00000000..3543f332 --- /dev/null +++ b/firmware/common/u128.c @@ -0,0 +1,88 @@ +/* + * Copyright 2026 Great Scott Gadgets + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "u128.h" + +/* From https://stackoverflow.com/a/58381061 */ + +u128 u128_multiply(uint64_t lhs, uint64_t rhs) +{ + uint64_t lo_lo = (lhs & 0xFFFFFFFF) * (rhs & 0xFFFFFFFF); + uint64_t hi_lo = (lhs >> 32) * (rhs & 0xFFFFFFFF); + uint64_t lo_hi = (lhs & 0xFFFFFFFF) * (rhs >> 32); + uint64_t hi_hi = (lhs >> 32) * (rhs >> 32); + uint64_t cross = ((lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi); + return (u128){ + .hi = ((hi_lo >> 32) + (cross >> 32) + hi_hi), + .lo = ((cross << 32) | (lo_lo & 0xFFFFFFFF)), + }; +} + +/* From https://stackoverflow.com/a/70052545 */ + +/* clang-format off */ + +#define SUBCcc(a,b,cy,t0,t1,t2) \ + (t0=(b)+cy, t1=(a), cy=t0= divisor + rem.lo = tmp.lo; + rem.hi = tmp.hi; + quot.lo |= 1; + } + } + + return quot; +} diff --git a/firmware/common/u128.h b/firmware/common/u128.h new file mode 100644 index 00000000..c51dc5f5 --- /dev/null +++ b/firmware/common/u128.h @@ -0,0 +1,32 @@ +/* + * Copyright 2026 Great Scott Gadgets + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include + +typedef struct { + uint64_t hi; + uint64_t lo; +} u128; + +u128 u128_multiply(uint64_t a, uint64_t b); +u128 u128_divide(u128 dvnd, u128 dvsr); diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index dfc67d9e..8f6698da 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -203,6 +203,7 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/adc.c ${PATH_HACKRF_FIRMWARE_COMMON}/da7219.c ${PATH_HACKRF_FIRMWARE_COMMON}/max283x.c + ${PATH_HACKRF_FIRMWARE_COMMON}/u128.c ) if(BOARD STREQUAL "RAD1O")