Почему бы просто не поместить маску и значение в нужное место?
#define BM_TEST_FIELD (0xfUL << 16)
#define BM_TEST_VALUE (0xaUL << 16)
#define mmioMaskInsert(reg, mask, value) \
(*(volatile u32 *)(reg) = (*(volatile u32 *)(reg) & ~(mask)) | value)
Тогда вы можете просто использовать его как:
mmioMaskInsert(reg, BM_TEST_FIELD, BM_TEST_VALUE);
Наверняка то, что у вас там, очень опасно. Запись в регистр часто может иметь побочные эффекты, и эти операции:
mem_reg &= ~(MASK);
mem_reg |= value;
фактически пишут в регистр дважды, а не один раз, как вы, вероятно, намереваетесь. Кроме того, почему не поддерживается маска 0? Что если я захочу записать во весь регистр (совпадение по таймеру или что-то в этом роде)? У вас есть другой макрос для этой операции? Если так, почему бы не использовать его как часть этой системы?
Еще одно замечание - возможно, было бы неплохо применить маску к значению, прежде чем помещать ее в регистр, в случае, если кто-то передает значение, которое имеет больше бит, чем маска. Что-то вроде:
#define maskInsert(r, m, v) \
(*(volatile u32 *)(r) = (*(volatile u32 *)r & ~(m)) | ((v) & ~(m)))