1 #include "ternary_fields.h"
5 #include "../platform/memory.h"
6 #include <rofl/datapath/pipeline/common/ternary_fields.h>
11 inline utern_t* __init_utern8(uint8_t value, uint8_t mask){
17 tern->type = UTERN8_T;
18 tern->value.u8 = value;
22 inline utern_t* __init_utern16(uint16_t value, uint16_t mask){
28 tern->type = UTERN16_T;
29 tern->value.u16 = value;
30 tern->mask.u16 = mask;
33 inline utern_t* __init_utern32(uint32_t value, uint32_t mask){
39 tern->type = UTERN32_T;
40 tern->value.u32 = value;
41 tern->mask.u32 = mask;
44 inline utern_t* __init_utern64(uint64_t value, uint64_t mask){
50 tern->type = UTERN64_T;
51 tern->value.u64 = value;
52 tern->mask.u64 = mask;
61 tern->type = UTERN128_T;
62 tern->value.u128 = value;
63 tern->mask.u128 = mask;
83 inline bool __utern_is_contained(
const utern_t* extensive_tern,
const utern_t* tern){
85 switch(extensive_tern->type){
90 return (extensive_tern->value.u8 & extensive_tern->mask.u8) == (tern->value.u8 & extensive_tern->mask.u8);
95 return (extensive_tern->value.u16 & extensive_tern->mask.u16) == (tern->value.u16 & extensive_tern->mask.u16);
100 return (extensive_tern->value.u32 & extensive_tern->mask.u32) == (tern->value.u32 & extensive_tern->mask.u32);
103 if(((extensive_tern->mask.u64 ^ tern->mask.u64) & extensive_tern->mask.u64) > 0)
105 return (extensive_tern->value.u64 & extensive_tern->mask.u64) == (tern->value.u64 & extensive_tern->mask.u64);
109 if((((extensive_tern->mask.low ^ tern->mask.low) & extensive_tern->mask.low) > 0 ) ||
110 (((extensive_tern->mask.high ^ tern->mask.high) & extensive_tern->mask.high) > 0 ) )
112 return ( (extensive_tern->value.low & extensive_tern->mask.low) == (tern->value.low & extensive_tern->mask.low) &&
113 (extensive_tern->value.high & extensive_tern->mask.high) == (tern->value.high & extensive_tern->mask.high) );
119 return ( (UINT128__T_LO(extensive_tern->value.u128) & UINT128__T_LO(extensive_tern->mask.u128)) == (UINT128__T_LO(tern->value.u128) & UINT128__T_LO(extensive_tern->mask.u128)) ) &&
120 ((UINT128__T_HI(extensive_tern->value.u128) & UINT128__T_HI(extensive_tern->mask.u128)) == (UINT128__T_HI(tern->value.u128) & UINT128__T_HI(extensive_tern->mask.u128)) );
132 inline bool __utern_equals(
const utern_t* tern1,
const utern_t* tern2){
133 switch(tern1->type) {
136 return (tern1->value.u8 == tern2->value.u8) && (tern1->mask.u8 == tern2->mask.u8);
139 return (tern1->value.u16 == tern2->value.u16) && (tern1->mask.u16 == tern2->mask.u16);
142 return (tern1->value.u32 == tern2->value.u32) && (tern1->mask.u32 == tern2->mask.u32);
145 return (tern1->value.u64 == tern2->value.u64) && (tern1->mask.u64 == tern2->mask.u64);
148 return (UINT128__T_LO(tern1->value.u128) == UINT128__T_LO(tern2->value.u128)) && (UINT128__T_LO(tern1->mask.u128) == UINT128__T_LO(tern2->mask.u128)) &&
149 (UINT128__T_HI(tern1->value.u128) == UINT128__T_HI(tern2->value.u128)) && (UINT128__T_HI(tern1->mask.u128) == UINT128__T_HI(tern2->mask.u128));
167 (tern1.value.u8 & tern1.mask.u8)
169 (tern2.value.u8 & tern2.mask.u8)
172 for(new_mask.u8=0xFF;new_mask.u8;new_mask.u8=new_mask.u8<<1)
173 if((diff.u8&new_mask.u8) == new_mask.u8)
break;
175 if(tern1.mask.u8 < new_mask.u8 || tern2.mask.u8 < new_mask.u8 )
179 return __init_utern8(tern1.value.u8,new_mask.u8);
188 (tern1.value.u16 & tern1.mask.u16)
190 (tern2.value.u16 & tern2.mask.u16)
193 for(new_mask.u16=0xFFFF;new_mask.u16;new_mask.u16=new_mask.u16<<1)
194 if((diff.u16&new_mask.u16) == new_mask.u16)
break;
196 if(tern1.mask.u16 < new_mask.u16 || tern2.mask.u16 < new_mask.u16 )
200 return __init_utern16(tern1.value.u16,new_mask.u16);
209 (tern1.value.u32 & tern1.mask.u32)
211 (tern2.value.u32 & tern2.mask.u32)
214 for(new_mask.u32=0xFFFFFFFF;new_mask.u32;new_mask.u32=new_mask.u32<<1)
215 if((diff.u32&new_mask.u32) == new_mask.u32)
break;
217 if(tern1.mask.u32 < new_mask.u32 || tern2.mask.u32 < new_mask.u32 )
221 return __init_utern32(tern1.value.u32,new_mask.u32);
230 (tern1.value.u64 & tern1.mask.u64)
232 (tern2.value.u64 & tern2.mask.u64)
235 for(new_mask.u64=0xFFFFFFFFFFFFFFFFULL;new_mask.u64;new_mask.u64=new_mask.u64<<1)
236 if((diff.u64&new_mask.u64) == new_mask.u64)
break;
241 if(tern1.mask.u64 < new_mask.u64 || tern2.mask.u64 < new_mask.u64 )
245 return __init_utern64(tern1.value.u64,new_mask.u64);
253 UINT128__T_LO(diff.u128) = ~( (UINT128__T_LO(tern1.value.u128) & UINT128__T_LO(tern1.mask.u128)) ^ (UINT128__T_LO(tern2.value.u128) & UINT128__T_LO(tern2.mask.u128)) );
254 UINT128__T_HI(diff.u128) = ~( (UINT128__T_HI(tern1.value.u128) & UINT128__T_HI(tern1.mask.u128)) ^ (UINT128__T_HI(tern2.value.u128) & UINT128__T_HI(tern2.mask.u128)) );
257 for(UINT128__T_LO(new_mask.u128)=0xFFFFFFFFFFFFFFFFULL;UINT128__T_LO(new_mask.u128);UINT128__T_LO(new_mask.u128)=UINT128__T_LO(new_mask.u128)<<1)
258 if((UINT128__T_LO(diff.u128)&UINT128__T_LO(new_mask.u128)) == UINT128__T_LO(new_mask.u128))
break;
260 if( (UINT128__T_LO(tern1.mask.u128) < UINT128__T_LO(new_mask.u128) || UINT128__T_LO(tern2.mask.u128) < UINT128__T_LO(new_mask.u128)) && UINT128__T_HI(diff.u128) == 0xffffffffffffffffULL )
263 if( UINT128__T_LO(new_mask.u128) && UINT128__T_HI(diff.u128) == 0xffffffffffffffffULL ){
264 UINT128__T_HI(new_mask.u128) = 0xffffffffffffffffULL;
265 return __init_utern128(tern1.value.u128,new_mask.u128);
269 for(UINT128__T_HI(new_mask.u128)=0xFFFFFFFFFFFFFFFFULL;UINT128__T_HI(new_mask.u128);UINT128__T_HI(new_mask.u128)=UINT128__T_HI(new_mask.u128)<<1)
270 if((UINT128__T_HI(diff.u128)&UINT128__T_HI(new_mask.u128)) == UINT128__T_HI(new_mask.u128))
break;
272 if(UINT128__T_HI(tern1.mask.u128)<UINT128__T_HI(new_mask.u128) || UINT128__T_HI(tern2.mask.u128) < UINT128__T_HI(new_mask.u128) )
275 if(UINT128__T_HI(new_mask.u128)){
276 UINT128__T_LO(new_mask.u128)=0x0000000000000000;
277 return __init_utern128(tern1.value.u128,new_mask.u128);