diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-10-27 22:31:38 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-10-27 22:31:38 -0600 |
commit | 4b85b09593fae1b72a6d64b09a7843f9a28dbe99 (patch) | |
tree | c66fbdf882d70a4228311a174736d52908d903b4 /src/Language/Fiddle/Compiler | |
parent | 5d3f21123b585fb1c43da9d854b04c61678405df (diff) | |
download | fiddle-4b85b09593fae1b72a6d64b09a7843f9a28dbe99.tar.gz fiddle-4b85b09593fae1b72a6d64b09a7843f9a28dbe99.tar.bz2 fiddle-4b85b09593fae1b72a6d64b09a7843f9a28dbe99.zip |
Enforce that registers are either 8, 16, 32, or 64 bits.
Fixed the issues where the output C code did not use correct register
sizes.
Diffstat (limited to 'src/Language/Fiddle/Compiler')
-rw-r--r-- | src/Language/Fiddle/Compiler/Backend/C.hs | 42 | ||||
-rw-r--r-- | src/Language/Fiddle/Compiler/ConsistencyCheck.hs | 28 | ||||
-rw-r--r-- | src/Language/Fiddle/Compiler/Qualification.hs | 18 |
3 files changed, 59 insertions, 29 deletions
diff --git a/src/Language/Fiddle/Compiler/Backend/C.hs b/src/Language/Fiddle/Compiler/Backend/C.hs index 26ea065..77eadf6 100644 --- a/src/Language/Fiddle/Compiler/Backend/C.hs +++ b/src/Language/Fiddle/Compiler/Backend/C.hs @@ -273,7 +273,8 @@ writeRegGet }, regFullPath = fullPath } - ) docComms = do + ) + docComms = do let fnName = qualifiedPathToIdentifier fullPath <> "__get" returnType = sizeToType size fieldName = basenamePart fullPath @@ -313,7 +314,8 @@ writeRegSet }, regFullPath = fullPath } - ) docComs = do + ) + docComs = do let fnName = qualifiedPathToIdentifier fullPath <> "__set" setType = sizeToType size fieldName = basenamePart fullPath @@ -370,16 +372,18 @@ pattern DefinedBitsP modifier bitsName bitsFullPath offset typeRef annot <- writeBitsGet :: StructName -> - String -> + QRegMetadata True -> QualifiedPath String -> N Bits -> RegisterBitsTypeRef 'Checked I A -> A -> M SIntf -writeBitsGet structName regName fullPath offset typeRef docComms = do +writeBitsGet structName regmeta fullPath offset typeRef docComms = do let fnName = qualifiedPathToIdentifier fullPath <> "__get" bitsName = basenamePart fullPath retType = typeRefBaseType typeRef + regName = basenamePart (regFullPath regmeta) + regCType = getRegCType regmeta text $ "inline static " <> retType <> " " text fnName @@ -404,13 +408,13 @@ writeBitsGet structName regName fullPath offset typeRef docComms = do withIndent $ do if null shiftArguments then do - text "unsigned shift_ = 0" + text $ regCType <> " shift_ = 0" else do - text "unsigned shift_ = " + text $ regCType <> " shift_ = " text $ Text.intercalate " + " shiftArguments text ";\n" - text "unsigned mask_ = " + text $ regCType <> " mask_ = " text $ typeRefToGetMask typeRef text " << shift_;\n" @@ -467,18 +471,26 @@ writeBitsGet structName regName fullPath offset typeRef docComms = do num = (1 `Data.Bits.shiftL` fromIntegral sz) - 1 in "0x" <> Text.pack (showHex num "") +getRegCType :: QRegMetadata True -> Text +getRegCType meta = + Text.pack $ + fromMaybe "unsigned" $ + sizeToType (size (unwrap (regSpan meta))) + writeBitsSet :: Bool -> StructName -> - String -> + QRegMetadata True -> QualifiedPath String -> N Bits -> RegisterBitsTypeRef 'Checked I A -> A -> M SIntf -writeBitsSet writeOnly structName regName fullPath offset typeRef docComms = do +writeBitsSet writeOnly structName regmeta fullPath offset typeRef docComms = do let fnName = qualifiedPathToIdentifier fullPath <> "__set" bitsName = basenamePart fullPath + regName = basenamePart (regFullPath regmeta) + regCType = getRegCType regmeta text "inline static void " text fnName @@ -498,10 +510,10 @@ writeBitsSet writeOnly structName regName fullPath offset typeRef docComms = do withIndent $ do let mask = typeRefToMask typeRef - text $ "unsigned mask_ = " <> mask <> ";\n" + text $ regCType <> " mask_ = " <> mask <> ";\n" unless (null shiftArguments) $ do text $ - "unsigned shift_ = " <> Text.intercalate " + " shiftArguments <> ";\n" + regCType <> " shift_ = " <> Text.intercalate " + " shiftArguments <> ";\n" text "mask_ <<= shift_;\n" text "int to_set_ = value" @@ -512,7 +524,7 @@ writeBitsSet writeOnly structName regName fullPath offset typeRef docComms = do text "to_set_ &= mask_;\n" unless writeOnly $ do - text $ "unsigned current_ = o->" <> Text.pack regName <> ";\n" + text $ regCType <> " current_ = o->" <> Text.pack regName <> ";\n" text "to_set_ = current_ ^ (current_ & mask_) ^ to_set_;\n" text $ "o->" <> Text.pack regName <> " = to_set_;\n" @@ -614,8 +626,6 @@ writeRegisterBody :: StructName -> QRegMetadata True -> RegisterBody Checked I A -> M SIntf writeRegisterBody structName regmeta = execWriterT . walk_ registerWalk where - regName = basenamePart (regFullPath regmeta) - registerWalk :: forall t. (Walk t, Typeable t) => @@ -632,8 +642,8 @@ writeRegisterBody structName regmeta = execWriterT . walk_ registerWalk sequence_ $ selectByModifier modifier - ( tell =<< lift (writeBitsGet structName regName fullPath offset typeRef annot), - tell =<< lift (writeBitsSet isWo structName regName fullPath offset typeRef annot) + ( tell =<< lift (writeBitsGet structName regmeta fullPath offset typeRef annot), + tell =<< lift (writeBitsSet isWo structName regmeta fullPath offset typeRef annot) ) -- text $ -- Text.pack $ diff --git a/src/Language/Fiddle/Compiler/ConsistencyCheck.hs b/src/Language/Fiddle/Compiler/ConsistencyCheck.hs index 3def59d..00a53dc 100644 --- a/src/Language/Fiddle/Compiler/ConsistencyCheck.hs +++ b/src/Language/Fiddle/Compiler/ConsistencyCheck.hs @@ -156,25 +156,33 @@ advanceObjTypeBody (ObjTypeBody us decls a) startOffset = do checkPositionAssertion (annot e) assertedPos offset return (ret, offset) (RegisterDecl qmeta mod ident size Nothing a) -> do - (sizeExpr, reifiedSize) <- advanceAndGetSize size - reifiedSizeBytes <- checkBitsSizeMod8 a reifiedSize + let declaredSize = regSzToBits (getLeft size) + reifiedSizeBytes <- checkBitsSizeMod8 a declaredSize let span = Present (FieldSpan offset reifiedSizeBytes) qmeta' = fmap (\q -> q {regSpan = span}) qmeta - doReturn (RegisterDecl qmeta' mod ident sizeExpr Nothing a) - =<< checkBitsSizeMod8 a reifiedSize + doReturn (RegisterDecl qmeta' mod ident (changeRight size) Nothing a) + =<< checkBitsSizeMod8 a declaredSize (RegisterDecl qmeta mod ident size (Just body) a) -> do - declaredSize <- expressionToIntM size - (actualSize, body') <- advanceRegisterBody 0 body + let declaredSize = regSzToBits (getLeft size) + (actualSize, body') <- advanceRegisterBody 0 body checkSizeMismatch a declaredSize actualSize - - (sizeExpr, reifiedSize) <- advanceAndGetSize size - reifiedSizeBytes <- checkBitsSizeMod8 a reifiedSize + reifiedSizeBytes <- checkBitsSizeMod8 a declaredSize let span = Present (FieldSpan offset reifiedSizeBytes) qmeta' = fmap (\q -> q {regSpan = span}) qmeta - doReturn (RegisterDecl qmeta' mod ident sizeExpr (Just body') a) reifiedSizeBytes + + doReturn + ( RegisterDecl + qmeta' + mod + ident + (changeRight size) + (Just body') + a + ) + reifiedSizeBytes (TypeSubStructure (Identity body) name a) -> do (size, body') <- advanceObjTypeBody body offset doReturn (TypeSubStructure (Identity body') name a) size diff --git a/src/Language/Fiddle/Compiler/Qualification.hs b/src/Language/Fiddle/Compiler/Qualification.hs index e8ab479..eae219e 100644 --- a/src/Language/Fiddle/Compiler/Qualification.hs +++ b/src/Language/Fiddle/Compiler/Qualification.hs @@ -177,6 +177,18 @@ instance AdvanceStage S RegisterBitsDecl where <$> advanceStage localState typ <*> pure an +getProperRegSize :: (stage .< Expanded ~ False) => Expression Bits stage F A -> M RegSz +getProperRegSize expr = do + v <- expressionToIntM expr + case v of + 8 -> return RegSz8 + 16 -> return RegSz16 + 32 -> return RegSz32 + 64 -> return RegSz64 + _ -> do + emitDiagnosticError "Exotic register size." (annot expr) + return RegSz32 + instance AdvanceStage S ObjTypeDecl where advanceStage localState = \case AssertPosStatement d e a -> @@ -202,7 +214,7 @@ instance AdvanceStage S ObjTypeDecl where (Present qRegMeta) (guarantee (ModifierKeyword Rw ann) mod) ident' - <$> advanceStage localState'' size + <$> progressBackM getProperRegSize size <*> mapM (advanceStage localState'') bod <*> pure ann ReservedDecl _ expr ann -> do @@ -222,7 +234,7 @@ instance AdvanceStage S ObjTypeDecl where (Present qRegMeta) (Guaranteed $ ModifierKeyword Pr ann) (Guaranteed ident) - <$> advanceStage localState expr + <$> fmap LeftV (getProperRegSize expr) <*> pure Nothing <*> pure ann TypeSubStructure bod name an -> do @@ -482,7 +494,7 @@ calculateTypeSize (ObjTypeBody bodyType decls _) = calculateDeclSize (undirected -> decl) = case decl of AssertPosStatement {} -> return 0 - RegisterDecl {regSize = size} -> fst . bitsToBytes <$> expressionToIntM size + RegisterDecl {regSize = size} -> fst . bitsToBytes <$> expressionToIntM (getRight size) ReservedDecl {reservedExpr = size} -> fst . bitsToBytes <$> expressionToIntM size TypeSubStructure {subStructureBody = b} -> calculateTypeSize =<< resolveOrFail b |