1# Copyright (c) Barefoot Networks, Inc. 2# Licensed under the Apache License, Version 2.0 (the "License") 3 4from p4_hlir.hlir import P4_AUTO_WIDTH 5from ebpfType import * 6from compilationException import * 7from programSerializer import ProgramSerializer 8 9 10class EbpfScalarType(EbpfType): 11 __doc__ = "Represents a scalar type" 12 def __init__(self, parent, widthInBits, isSigned, config): 13 super(EbpfScalarType, self).__init__(None) 14 assert isinstance(widthInBits, int) 15 assert isinstance(isSigned, bool) 16 self.width = widthInBits 17 self.isSigned = isSigned 18 self.config = config 19 if widthInBits is P4_AUTO_WIDTH: 20 raise NotSupportedException("{0} Variable-width field", parent) 21 22 def widthInBits(self): 23 return self.width 24 25 @staticmethod 26 def bytesRequired(width): 27 return (width + 7) / 8 28 29 def asString(self): 30 if self.isSigned: 31 prefix = self.config.iprefix 32 else: 33 prefix = self.config.uprefix 34 35 if self.width <= 8: 36 name = prefix + "8" 37 elif self.width <= 16: 38 name = prefix + "16" 39 elif self.width <= 32: 40 name = prefix + "32" 41 else: 42 name = "char*" 43 return name 44 45 def alignment(self): 46 if self.width <= 8: 47 return 1 48 elif self.width <= 16: 49 return 2 50 elif self.width <= 32: 51 return 4 52 else: 53 return 1 # Char array 54 55 def serialize(self, serializer): 56 assert isinstance(serializer, ProgramSerializer) 57 serializer.append(self.asString()) 58 59 def declareArray(self, serializer, identifier, size): 60 raise CompilationException( 61 True, "Arrays of base type not expected in P4") 62 63 def declare(self, serializer, identifier, asPointer): 64 assert isinstance(serializer, ProgramSerializer) 65 assert isinstance(asPointer, bool) 66 assert isinstance(identifier, str) 67 68 if self.width <= 32: 69 self.serialize(serializer) 70 if asPointer: 71 serializer.append("*") 72 serializer.space() 73 serializer.append(identifier) 74 else: 75 if asPointer: 76 serializer.append("char*") 77 else: 78 serializer.appendFormat( 79 "char {0}[{1}]", identifier, 80 EbpfScalarType.bytesRequired(self.width)) 81 82 def emitInitializer(self, serializer): 83 assert isinstance(serializer, ProgramSerializer) 84 serializer.append("0") 85