@@ -55,12 +55,9 @@ def __init__(self, inst: parser.InstDef):
55
55
]
56
56
self .output_effects = self .outputs # For consistency/completeness
57
57
58
- def write (self , f : typing .TextIO , indent : str , dedent : int = 0 ) -> None :
58
+ def write (self , f : typing .TextIO , indent : str ) -> None :
59
59
"""Write one instruction, sans prologue and epilogue."""
60
- if dedent < 0 :
61
- indent += " " * - dedent # DO WE NEED THIS?
62
-
63
- # Get cache offset and maybe assert that it is correct
60
+ # Write a static assertion that a family's cache size is correct
64
61
if family := self .family :
65
62
if self .name == family .members [0 ]:
66
63
if cache_size := family .size :
@@ -69,30 +66,6 @@ def write(self, f: typing.TextIO, indent: str, dedent: int = 0) -> None:
69
66
f'{ self .cache_offset } , "incorrect cache size");\n '
70
67
)
71
68
72
- # Write cache effect variable declarations
73
- cache_offset = 0
74
- for ceffect in self .cache_effects :
75
- if ceffect .name != UNUSED :
76
- bits = ceffect .size * BITS_PER_CODE_UNIT
77
- if bits == 64 :
78
- # NOTE: We assume that 64-bit data in the cache
79
- # is always an object pointer.
80
- # If this becomes false, we need a way to specify
81
- # syntactically what type the cache data is.
82
- f .write (
83
- f"{ indent } PyObject *{ ceffect .name } = "
84
- f"read_obj(next_instr + { cache_offset } );\n "
85
- )
86
- else :
87
- f .write (f"{ indent } uint{ bits } _t { ceffect .name } = " )
88
- if ceffect .size == 1 :
89
- # There is no read_u16() helper function.
90
- f .write (f"*(next_instr + { cache_offset } );\n " )
91
- else :
92
- f .write (f"read_u{ bits } (next_instr + { cache_offset } );\n " )
93
- cache_offset += ceffect .size
94
- assert cache_offset == self .cache_offset
95
-
96
69
# Write input stack effect variable declarations and initializations
97
70
for i , seffect in enumerate (reversed (self .input_effects ), 1 ):
98
71
if seffect .name != UNUSED :
@@ -105,7 +78,7 @@ def write(self, f: typing.TextIO, indent: str, dedent: int = 0) -> None:
105
78
if seffect .name not in input_names :
106
79
f .write (f"{ indent } PyObject *{ seffect .name } ;\n " )
107
80
108
- self .write_body (f , indent , dedent )
81
+ self .write_body (f , indent + " " , 0 )
109
82
110
83
# Skip the rest if the block always exits
111
84
if always_exits (self .block ):
@@ -127,12 +100,31 @@ def write(self, f: typing.TextIO, indent: str, dedent: int = 0) -> None:
127
100
if seffect .name not in unmoved_names :
128
101
f .write (f"{ indent } POKE({ i + 1 } , { seffect .name } );\n " )
129
102
130
- # Write cache effect
131
- if self .cache_offset :
132
- f .write (f"{ indent } next_instr += { self .cache_offset } ;\n " )
133
-
134
- def write_body (self , f : typing .TextIO , ndent : str , dedent : int ) -> None :
103
+ def write_body (self , f : typing .TextIO , indent : str , dedent : int ) -> None :
135
104
"""Write the instruction body."""
105
+ # Write cache effect variable declarations and initializations
106
+ cache_offset = 0
107
+ for ceffect in self .cache_effects :
108
+ if ceffect .name != UNUSED :
109
+ bits = ceffect .size * BITS_PER_CODE_UNIT
110
+ if bits == 64 :
111
+ # NOTE: We assume that 64-bit data in the cache
112
+ # is always an object pointer.
113
+ # If this becomes false, we need a way to specify
114
+ # syntactically what type the cache data is.
115
+ f .write (
116
+ f"{ indent } PyObject *{ ceffect .name } = "
117
+ f"read_obj(next_instr + { cache_offset } );\n "
118
+ )
119
+ else :
120
+ f .write (f"{ indent } uint{ bits } _t { ceffect .name } = " )
121
+ if ceffect .size == 1 :
122
+ # There is no read_u16() helper function.
123
+ f .write (f"*(next_instr + { cache_offset } );\n " )
124
+ else :
125
+ f .write (f"read_u{ bits } (next_instr + { cache_offset } );\n " )
126
+ cache_offset += ceffect .size
127
+ assert cache_offset == self .cache_offset
136
128
137
129
# Get lines of text with proper dedent
138
130
blocklines = self .block .to_text (dedent = dedent ).splitlines (True )
@@ -175,6 +167,10 @@ def write_body(self, f: typing.TextIO, ndent: str, dedent: int) -> None:
175
167
else :
176
168
f .write (line )
177
169
170
+ # Write cache effect
171
+ if self .cache_offset :
172
+ f .write (f"{ indent } next_instr += { self .cache_offset } ;\n " )
173
+
178
174
179
175
@dataclasses .dataclass
180
176
class SuperComponent :
@@ -238,7 +234,7 @@ def super_macro_analysis(
238
234
"""
239
235
lowest = current = highest = 0
240
236
for instr in components :
241
- if instr .cache_effects :
237
+ if self . kind == "macro" and instr .cache_effects :
242
238
a .error (
243
239
f"Super-instruction { self .name !r} has cache effects in { instr .name !r} " ,
244
240
instr ,
0 commit comments