1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
|
# -*- coding: utf-8 -*-
#
# AWL simulator - instructions
#
# Copyright 2012-2017 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
from __future__ import division, absolute_import, print_function, unicode_literals
#from awlsim.common.cython_support cimport * #@cy
from awlsim.common.compat import *
from awlsim.common.cpuconfig import *
from awlsim.common.datatypehelpers import * #+cimport
from awlsim.common.exceptions import *
from awlsim.common.util import *
from awlsim.core.instructions.types import * #+cimport
from awlsim.core.instructions.parentinfo import *
from awlsim.core.operatortypes import * #+cimport
from awlsim.core.operators import * #+cimport
from awlsim.awlcompiler.optrans import *
class AwlInsn(object): #+cdef
"""AWL instruction base class.
"""
TYPE_U = AwlInsnTypes.TYPE_U
TYPE_UN = AwlInsnTypes.TYPE_UN
TYPE_O = AwlInsnTypes.TYPE_O
TYPE_ON = AwlInsnTypes.TYPE_ON
TYPE_X = AwlInsnTypes.TYPE_X
TYPE_XN = AwlInsnTypes.TYPE_XN
TYPE_UB = AwlInsnTypes.TYPE_UB
TYPE_UNB = AwlInsnTypes.TYPE_UNB
TYPE_OB = AwlInsnTypes.TYPE_OB
TYPE_ONB = AwlInsnTypes.TYPE_ONB
TYPE_XB = AwlInsnTypes.TYPE_XB
TYPE_XNB = AwlInsnTypes.TYPE_XNB
TYPE_BEND = AwlInsnTypes.TYPE_BEND
TYPE_ASSIGN = AwlInsnTypes.TYPE_ASSIGN
TYPE_R = AwlInsnTypes.TYPE_R
TYPE_S = AwlInsnTypes.TYPE_S
TYPE_NOT = AwlInsnTypes.TYPE_NOT
TYPE_SET = AwlInsnTypes.TYPE_SET
TYPE_CLR = AwlInsnTypes.TYPE_CLR
TYPE_SAVE = AwlInsnTypes.TYPE_SAVE
TYPE_FN = AwlInsnTypes.TYPE_FN
TYPE_FP = AwlInsnTypes.TYPE_FP
TYPE_EQ_I = AwlInsnTypes.TYPE_EQ_I
TYPE_NE_I = AwlInsnTypes.TYPE_NE_I
TYPE_GT_I = AwlInsnTypes.TYPE_GT_I
TYPE_LT_I = AwlInsnTypes.TYPE_LT_I
TYPE_GE_I = AwlInsnTypes.TYPE_GE_I
TYPE_LE_I = AwlInsnTypes.TYPE_LE_I
TYPE_EQ_D = AwlInsnTypes.TYPE_EQ_D
TYPE_NE_D = AwlInsnTypes.TYPE_NE_D
TYPE_GT_D = AwlInsnTypes.TYPE_GT_D
TYPE_LT_D = AwlInsnTypes.TYPE_LT_D
TYPE_GE_D = AwlInsnTypes.TYPE_GE_D
TYPE_LE_D = AwlInsnTypes.TYPE_LE_D
TYPE_EQ_R = AwlInsnTypes.TYPE_EQ_R
TYPE_NE_R = AwlInsnTypes.TYPE_NE_R
TYPE_GT_R = AwlInsnTypes.TYPE_GT_R
TYPE_LT_R = AwlInsnTypes.TYPE_LT_R
TYPE_GE_R = AwlInsnTypes.TYPE_GE_R
TYPE_LE_R = AwlInsnTypes.TYPE_LE_R
TYPE_BTI = AwlInsnTypes.TYPE_BTI
TYPE_ITB = AwlInsnTypes.TYPE_ITB
TYPE_BTD = AwlInsnTypes.TYPE_BTD
TYPE_ITD = AwlInsnTypes.TYPE_ITD
TYPE_DTB = AwlInsnTypes.TYPE_DTB
TYPE_DTR = AwlInsnTypes.TYPE_DTR
TYPE_INVI = AwlInsnTypes.TYPE_INVI
TYPE_INVD = AwlInsnTypes.TYPE_INVD
TYPE_NEGI = AwlInsnTypes.TYPE_NEGI
TYPE_NEGD = AwlInsnTypes.TYPE_NEGD
TYPE_NEGR = AwlInsnTypes.TYPE_NEGR
TYPE_TAW = AwlInsnTypes.TYPE_TAW
TYPE_TAD = AwlInsnTypes.TYPE_TAD
TYPE_RND = AwlInsnTypes.TYPE_RND
TYPE_TRUNC = AwlInsnTypes.TYPE_TRUNC
TYPE_RNDP = AwlInsnTypes.TYPE_RNDP
TYPE_RNDN = AwlInsnTypes.TYPE_RNDN
TYPE_FR = AwlInsnTypes.TYPE_FR
TYPE_L = AwlInsnTypes.TYPE_L
TYPE_LC = AwlInsnTypes.TYPE_LC
TYPE_ZV = AwlInsnTypes.TYPE_ZV
TYPE_ZR = AwlInsnTypes.TYPE_ZR
TYPE_AUF = AwlInsnTypes.TYPE_AUF
TYPE_TDB = AwlInsnTypes.TYPE_TDB
TYPE_SPA = AwlInsnTypes.TYPE_SPA
TYPE_SPL = AwlInsnTypes.TYPE_SPL
TYPE_SPB = AwlInsnTypes.TYPE_SPB
TYPE_SPBN = AwlInsnTypes.TYPE_SPBN
TYPE_SPBB = AwlInsnTypes.TYPE_SPBB
TYPE_SPBNB = AwlInsnTypes.TYPE_SPBNB
TYPE_SPBI = AwlInsnTypes.TYPE_SPBI
TYPE_SPBIN = AwlInsnTypes.TYPE_SPBIN
TYPE_SPO = AwlInsnTypes.TYPE_SPO
TYPE_SPS = AwlInsnTypes.TYPE_SPS
TYPE_SPZ = AwlInsnTypes.TYPE_SPZ
TYPE_SPN = AwlInsnTypes.TYPE_SPN
TYPE_SPP = AwlInsnTypes.TYPE_SPP
TYPE_SPM = AwlInsnTypes.TYPE_SPM
TYPE_SPPZ = AwlInsnTypes.TYPE_SPPZ
TYPE_SPMZ = AwlInsnTypes.TYPE_SPMZ
TYPE_SPU = AwlInsnTypes.TYPE_SPU
TYPE_LOOP = AwlInsnTypes.TYPE_LOOP
TYPE_PL_I = AwlInsnTypes.TYPE_PL_I
TYPE_MI_I = AwlInsnTypes.TYPE_MI_I
TYPE_MU_I = AwlInsnTypes.TYPE_MU_I
TYPE_DI_I = AwlInsnTypes.TYPE_DI_I
TYPE_PL = AwlInsnTypes.TYPE_PL
TYPE_PL_D = AwlInsnTypes.TYPE_PL_D
TYPE_MI_D = AwlInsnTypes.TYPE_MI_D
TYPE_MU_D = AwlInsnTypes.TYPE_MU_D
TYPE_DI_D = AwlInsnTypes.TYPE_DI_D
TYPE_MOD = AwlInsnTypes.TYPE_MOD
TYPE_PL_R = AwlInsnTypes.TYPE_PL_R
TYPE_MI_R = AwlInsnTypes.TYPE_MI_R
TYPE_MU_R = AwlInsnTypes.TYPE_MU_R
TYPE_DI_R = AwlInsnTypes.TYPE_DI_R
TYPE_ABS = AwlInsnTypes.TYPE_ABS
TYPE_SQR = AwlInsnTypes.TYPE_SQR
TYPE_SQRT = AwlInsnTypes.TYPE_SQRT
TYPE_EXP = AwlInsnTypes.TYPE_EXP
TYPE_LN = AwlInsnTypes.TYPE_LN
TYPE_SIN = AwlInsnTypes.TYPE_SIN
TYPE_COS = AwlInsnTypes.TYPE_COS
TYPE_TAN = AwlInsnTypes.TYPE_TAN
TYPE_ASIN = AwlInsnTypes.TYPE_ASIN
TYPE_ACOS = AwlInsnTypes.TYPE_ACOS
TYPE_ATAN = AwlInsnTypes.TYPE_ATAN
TYPE_LAR1 = AwlInsnTypes.TYPE_LAR1
TYPE_LAR2 = AwlInsnTypes.TYPE_LAR2
TYPE_T = AwlInsnTypes.TYPE_T
TYPE_TAR = AwlInsnTypes.TYPE_TAR
TYPE_TAR1 = AwlInsnTypes.TYPE_TAR1
TYPE_TAR2 = AwlInsnTypes.TYPE_TAR2
TYPE_BE = AwlInsnTypes.TYPE_BE
TYPE_BEB = AwlInsnTypes.TYPE_BEB
TYPE_BEA = AwlInsnTypes.TYPE_BEA
TYPE_CALL = AwlInsnTypes.TYPE_CALL
TYPE_CC = AwlInsnTypes.TYPE_CC
TYPE_UC = AwlInsnTypes.TYPE_UC
TYPE_MCRB = AwlInsnTypes.TYPE_MCRB
TYPE_BMCR = AwlInsnTypes.TYPE_BMCR
TYPE_MCRA = AwlInsnTypes.TYPE_MCRA
TYPE_MCRD = AwlInsnTypes.TYPE_MCRD
TYPE_SSI = AwlInsnTypes.TYPE_SSI
TYPE_SSD = AwlInsnTypes.TYPE_SSD
TYPE_SLW = AwlInsnTypes.TYPE_SLW
TYPE_SRW = AwlInsnTypes.TYPE_SRW
TYPE_SLD = AwlInsnTypes.TYPE_SLD
TYPE_SRD = AwlInsnTypes.TYPE_SRD
TYPE_RLD = AwlInsnTypes.TYPE_RLD
TYPE_RRD = AwlInsnTypes.TYPE_RRD
TYPE_RLDA = AwlInsnTypes.TYPE_RLDA
TYPE_RRDA = AwlInsnTypes.TYPE_RRDA
TYPE_SI = AwlInsnTypes.TYPE_SI
TYPE_SV = AwlInsnTypes.TYPE_SV
TYPE_SE = AwlInsnTypes.TYPE_SE
TYPE_SS = AwlInsnTypes.TYPE_SS
TYPE_SA = AwlInsnTypes.TYPE_SA
TYPE_UW = AwlInsnTypes.TYPE_UW
TYPE_OW = AwlInsnTypes.TYPE_OW
TYPE_XOW = AwlInsnTypes.TYPE_XOW
TYPE_UD = AwlInsnTypes.TYPE_UD
TYPE_OD = AwlInsnTypes.TYPE_OD
TYPE_XOD = AwlInsnTypes.TYPE_XOD
TYPE_TAK = AwlInsnTypes.TYPE_TAK
TYPE_PUSH = AwlInsnTypes.TYPE_PUSH
TYPE_POP = AwlInsnTypes.TYPE_POP
TYPE_ENT = AwlInsnTypes.TYPE_ENT
TYPE_LEAVE = AwlInsnTypes.TYPE_LEAVE
TYPE_INC = AwlInsnTypes.TYPE_INC
TYPE_DEC = AwlInsnTypes.TYPE_DEC
TYPE_INCAR1 = AwlInsnTypes.TYPE_INCAR1
TYPE_INCAR2 = AwlInsnTypes.TYPE_INCAR2
TYPE_BLD = AwlInsnTypes.TYPE_BLD
TYPE_NOP = AwlInsnTypes.TYPE_NOP
TYPE_EXTENDED = AwlInsnTypes.TYPE_EXTENDED
TYPE_ASSERT_EQ = AwlInsnTypes.TYPE_ASSERT_EQ
TYPE_ASSERT_EQ_R = AwlInsnTypes.TYPE_ASSERT_EQ_R
TYPE_ASSERT_NE = AwlInsnTypes.TYPE_ASSERT_NE
TYPE_ASSERT_GT = AwlInsnTypes.TYPE_ASSERT_GT
TYPE_ASSERT_LT = AwlInsnTypes.TYPE_ASSERT_LT
TYPE_ASSERT_GE = AwlInsnTypes.TYPE_ASSERT_GE
TYPE_ASSERT_LE = AwlInsnTypes.TYPE_ASSERT_LE
TYPE_SLEEP = AwlInsnTypes.TYPE_SLEEP
TYPE_STWRST = AwlInsnTypes.TYPE_STWRST
TYPE_FEATURE = AwlInsnTypes.TYPE_FEATURE
TYPE_GENERIC_CALL = AwlInsnTypes.TYPE_GENERIC_CALL
TYPE_INLINE_AWL = AwlInsnTypes.TYPE_INLINE_AWL
english2german = AwlInsnTypes.english2german
german2english = AwlInsnTypes.german2english
name2type_german = AwlInsnTypes.name2type_german
type2name_german = AwlInsnTypes.type2name_german
name2type_english = AwlInsnTypes.name2type_english
type2name_english = AwlInsnTypes.type2name_english
__slots__ = (
"cpu",
"insnType",
"ip",
"ops",
"opCount",
"op0",
"op1",
"params",
"labelStr",
"commentStr",
"parentInfo",
"_widths_1",
"_widths_8_16_32",
"_widths_16",
"_widths_32",
"_widths_scalar",
"_widths_all",
)
def __init__(self, cpu, insnType, rawInsn=None, ops=None):
"""Initialize base instruction.
"""
self.parentInfo = AwlInsnParentInfo() # Parent information
self.cpu = cpu # S7CPU() or None
self.insnType = insnType # TYPE_...
self.parentInfo.rawInsn = rawInsn # RawAwlInsn() or None
self.ip = 0 # Instruction pointer (IP)
self.ops = ops or [] # AwlOperator()s
self.params = () # Parameter assignments (for CALL)
self.labelStr = None # Optional label string.
self.commentStr = "" # Optional comment string.
# Local copy of commonly used fetch/store widths.
self._widths_1 = AwlOperatorWidths.WIDTH_MASK_1
self._widths_8_16_32 = AwlOperatorWidths.WIDTH_MASK_8_16_32
self._widths_16 = AwlOperatorWidths.WIDTH_MASK_16
self._widths_32 = AwlOperatorWidths.WIDTH_MASK_32
self._widths_scalar = AwlOperatorWidths.WIDTH_MASK_SCALAR
self._widths_all = AwlOperatorWidths.WIDTH_MASK_ALL
if rawInsn and ops is None:
opTrans = AwlOpTranslator(self)
opTrans.translateFromRawInsn(rawInsn)
self.__setupOpQuickRef()
def __setupOpQuickRef(self):
# Add a quick reference to the first and the second operator.
self.opCount = len(self.ops)
if self.opCount >= 1:
self.op0 = self.ops[0]
if self.opCount >= 2:
self.op1 = self.ops[1]
def finalSetup(self):
"""Run the final setup steps.
This method has to be called before the
instruction can be run for the first time.
"""
self.__setupOpQuickRef()
def staticSanityChecks(self):
"""Run static sanity checks.
"""
pass # Default: No sanity checks
def assertOpCount(self, counts):
"""Check whether we have the required operator count.
counts is a list/set/int of possible counts.
"""
assert(self.opCount == len_u32(self.ops))
counts = toList(counts)
if self.opCount not in counts:
raise AwlSimError("Invalid number of operators. "
"Expected %s." % listToHumanStr(counts),
insn=self)
def getMnemonics(self):
"""Return the MNEMONICS_... setting for this instruction.
Returns None, if the mnemonics setting is unknown.
"""
if self.cpu:
return self.cpu.getMnemonics()
return None
def getRawInsn(self):
return self.parentInfo.rawInsn
def hasLabel(self):
"""Returns True, if this insn has a label.
"""
if self.labelStr is not None:
return bool(self.labelStr)
if self.parentInfo.rawInsn:
return self.parentInfo.rawInsn.hasLabel()
return False
def getLabel(self):
"""Returns the label string.
"""
if self.labelStr is not None:
return self.labelStr
if self.parentInfo.rawInsn:
return self.parentInfo.rawInsn.getLabel()
return None
def setLabel(self, labelStr):
self.labelStr = labelStr or ""
def getIP(self):
return self.ip
def setIP(self, newIp):
self.ip = newIp
def getCpu(self):
return self.cpu
def getSourceId(self):
if not self.parentInfo.rawInsn:
return None
return self.parentInfo.rawInsn.getSourceId()
def getLineNr(self):
if not self.parentInfo.rawInsn:
return -1
return self.parentInfo.rawInsn.getLineNr()
def run(self): #+cdef
"""Run the instruction.
The default implementation does nothing.
"""
pass #@nocov
def _warnDeprecated(self, moreText=""):
lineNrStr = ""
lineNr = self.getLineNr()
if lineNr >= 0:
lineNrStr = " at line %d" % lineNr
if moreText:
moreText = "\n%s" % moreText
printWarning("Found DEPRECATED instruction%s:\n %s%s" % (
lineNrStr, str(self), moreText))
def getStr(self, compact=True, withSemicolon=False, withComment=False):
ret = []
if self.hasLabel():
labelStr = self.getLabel() + ":"
ret.append(labelStr)
nrPad = 1
if not compact:
nrPad = 8 - len(labelStr)
ret.append(" " * nrPad)
else:
if not compact:
ret.append(" " * 8)
type2name = AwlInsn.type2name_english
if self.getMnemonics() == S7CPUConfig.MNEMONICS_DE:
type2name = AwlInsn.type2name_german
try:
name = type2name[self.insnType]
except KeyError: #@nocov
name = "<unknown type %d>" % self.insnType
ret.append(name)
if self.ops:
if compact:
ret.append(" ")
else:
ret.append(" " * (8 - len(name)))
ret.append(", ".join(str(op) for op in self.ops))
if self.params:
ret.append(" ( ")
ret.append(", ".join(str(param) for param in self.params))
ret.append(" )")
if withSemicolon:
ret.append(";")
text = "".join(ret)
if withComment and (self.commentStr or self.parentInfo):
text += " " * (40 - len(text))
text += "// "
if self.commentStr:
text += self.commentStr
if self.parentInfo:
text += " "
if self.parentInfo:
text += str(self.parentInfo)
return text
def __repr__(self):
return self.getStr()
# Sanity check of english2german table
assert(all(germanName in AwlInsn.name2type_german \
for englishName, germanName in dictItems(AwlInsn.english2german)))
|