Add keyword parameters and list-valued arguments to
instruction format functions in ISA description language. Take advantage of these features to clean up memory instruction definitions in Alpha. arch/alpha/isa/decoder.isa: arch/alpha/isa/mem.isa: arch/alpha/isa/pal.isa: Take advantage of new keyword parameters to disambiguate instruction vs. memory-request flags, and to provide a default EA calculation for memory ops (since 99% of them are the same). arch/isa_parser.py: Add two new features to instruction format functions: - Keyword parameters, a la Python. - List-valued arguments. Also export makeList() function to Python code blocks, as this is handy for dealing with flags. --HG-- extra : convert_revision : 99bbbaa2e765230aa96b6a06ed193793325f9fb0
This commit is contained in:
parent
59ba3d463c
commit
3cc6c59582
4 changed files with 199 additions and 98 deletions
|
@ -34,47 +34,47 @@ decode OPCODE default Unknown::unknown() {
|
|||
}
|
||||
|
||||
format LoadOrNop {
|
||||
0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }});
|
||||
0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }});
|
||||
0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }});
|
||||
0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }});
|
||||
0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED);
|
||||
0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED);
|
||||
0x0a: ldbu({{ Ra.uq = Mem.ub; }});
|
||||
0x0c: ldwu({{ Ra.uq = Mem.uw; }});
|
||||
0x0b: ldq_u({{ Ra = Mem.uq; }}, ea_code = {{ EA = (Rb + disp) & ~7; }});
|
||||
0x23: ldt({{ Fa = Mem.df; }});
|
||||
0x2a: ldl_l({{ Ra.sl = Mem.sl; }}, mem_flags = LOCKED);
|
||||
0x2b: ldq_l({{ Ra.uq = Mem.uq; }}, mem_flags = LOCKED);
|
||||
0x20: MiscPrefetch::copy_load({{ EA = Ra; }},
|
||||
{{ fault = xc->copySrcTranslate(EA); }},
|
||||
IsMemRef, IsLoad, IsCopy);
|
||||
inst_flags = [IsMemRef, IsLoad, IsCopy]);
|
||||
}
|
||||
|
||||
format LoadOrPrefetch {
|
||||
0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }});
|
||||
0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT);
|
||||
0x28: ldl({{ Ra.sl = Mem.sl; }});
|
||||
0x29: ldq({{ Ra.uq = Mem.uq; }}, pf_flags = EVICT_NEXT);
|
||||
// IsFloating flag on lds gets the prefetch to disassemble
|
||||
// using f31 instead of r31... funcitonally it's unnecessary
|
||||
0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }},
|
||||
PF_EXCLUSIVE, IsFloating);
|
||||
0x22: lds({{ Fa.uq = s_to_t(Mem.ul); }},
|
||||
pf_flags = PF_EXCLUSIVE, inst_flags = IsFloating);
|
||||
}
|
||||
|
||||
format Store {
|
||||
0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }});
|
||||
0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }});
|
||||
0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }});
|
||||
0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }});
|
||||
0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }});
|
||||
0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }});
|
||||
0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }});
|
||||
0x0e: stb({{ Mem.ub = Ra<7:0>; }});
|
||||
0x0d: stw({{ Mem.uw = Ra<15:0>; }});
|
||||
0x2c: stl({{ Mem.ul = Ra<31:0>; }});
|
||||
0x2d: stq({{ Mem.uq = Ra.uq; }});
|
||||
0x0f: stq_u({{ Mem.uq = Ra.uq; }}, {{ EA = (Rb + disp) & ~7; }});
|
||||
0x26: sts({{ Mem.ul = t_to_s(Fa.uq); }});
|
||||
0x27: stt({{ Mem.df = Fa; }});
|
||||
0x24: MiscPrefetch::copy_store({{ EA = Rb; }},
|
||||
{{ fault = xc->copy(EA); }},
|
||||
IsMemRef, IsStore, IsCopy);
|
||||
inst_flags = [IsMemRef, IsStore, IsCopy]);
|
||||
}
|
||||
|
||||
format StoreCond {
|
||||
0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }},
|
||||
0x2e: stl_c({{ Mem.ul = Ra<31:0>; }},
|
||||
{{
|
||||
uint64_t tmp = write_result;
|
||||
// see stq_c
|
||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
||||
}}, LOCKED);
|
||||
0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }},
|
||||
}}, mem_flags = LOCKED);
|
||||
0x2f: stq_c({{ Mem.uq = Ra; }},
|
||||
{{
|
||||
uint64_t tmp = write_result;
|
||||
// If the write operation returns 0 or 1, then
|
||||
|
@ -85,7 +85,7 @@ decode OPCODE default Unknown::unknown() {
|
|||
// mailbox access, and we don't update the
|
||||
// result register at all.
|
||||
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
|
||||
}}, LOCKED);
|
||||
}}, mem_flags = LOCKED);
|
||||
}
|
||||
|
||||
format IntegerOperate {
|
||||
|
@ -607,8 +607,9 @@ decode OPCODE default Unknown::unknown() {
|
|||
format MiscPrefetch {
|
||||
0xf800: wh64({{ EA = Rb & ~ULL(63); }},
|
||||
{{ xc->writeHint(EA, 64, memAccessFlags); }},
|
||||
IsMemRef, IsDataPrefetch, IsStore, MemWriteOp,
|
||||
NO_FAULT);
|
||||
mem_flags = NO_FAULT,
|
||||
inst_flags = [IsMemRef, IsDataPrefetch,
|
||||
IsStore, MemWriteOp]);
|
||||
}
|
||||
|
||||
format BasicOperate {
|
||||
|
|
|
@ -407,16 +407,12 @@ def template LoadPrefetchCheckDecode {{
|
|||
|
||||
|
||||
let {{
|
||||
def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
|
||||
base_class = 'MemoryDisp32', flags = [],
|
||||
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code = '', base_class = 'MemoryDisp32',
|
||||
decode_template = BasicDecode, exec_template_base = ''):
|
||||
# Segregate flags into instruction flags (handled by InstObjParams)
|
||||
# and memory access flags (handled here).
|
||||
|
||||
# Would be nice to autogenerate this list, but oh well.
|
||||
valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE']
|
||||
mem_flags = [f for f in flags if f in valid_mem_flags]
|
||||
inst_flags = [f for f in flags if f not in valid_mem_flags]
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
@ -469,31 +465,39 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
|
|||
}};
|
||||
|
||||
|
||||
def format LoadOrNop(ea_code, memacc_code, *flags) {{
|
||||
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = LoadNopCheckDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
// Note that the flags passed in apply only to the prefetch version
|
||||
def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
|
||||
def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], pf_flags = [], inst_flags = []) {{
|
||||
# declare the load instruction object and generate the decode block
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code,
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
decode_template = LoadPrefetchCheckDecode,
|
||||
exec_template_base = 'Load')
|
||||
|
||||
# Declare the prefetch instruction object.
|
||||
|
||||
# convert flags from tuple to list to make them mutable
|
||||
pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT']
|
||||
# Make sure flag args are lists so we can mess with them.
|
||||
mem_flags = makeList(mem_flags)
|
||||
pf_flags = makeList(pf_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
|
||||
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
|
||||
'IsDataPrefetch', 'MemReadOp']
|
||||
|
||||
(pf_header_output, pf_decoder_output, _, pf_exec_output) = \
|
||||
LoadStoreBase(name, Name + 'Prefetch', ea_code,
|
||||
'xc->prefetch(EA, memAccessFlags);',
|
||||
flags = pf_flags, exec_template_base = 'Misc')
|
||||
pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
|
||||
|
||||
header_output += pf_header_output
|
||||
decoder_output += pf_decoder_output
|
||||
|
@ -501,24 +505,28 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
|
|||
}};
|
||||
|
||||
|
||||
def format Store(ea_code, memacc_code, *flags) {{
|
||||
def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{
|
||||
def format StoreCond(memacc_code, postacc_code,
|
||||
ea_code = {{ EA = Rb + disp; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code,
|
||||
flags = flags, exec_template_base = 'Store')
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
postacc_code, exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
|
||||
def format MiscPrefetch(ea_code, memacc_code, *flags) {{
|
||||
def format MiscPrefetch(ea_code, memacc_code,
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
|
||||
}};
|
||||
|
||||
|
|
|
@ -198,23 +198,25 @@ output decoder {{
|
|||
def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
flags = flags, base_class = 'HwLoadStore',
|
||||
exec_template_base = 'Load')
|
||||
mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore', exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
|
||||
def format HwStore(ea_code, memacc_code, class_ext, *flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
flags = flags, base_class = 'HwLoadStore',
|
||||
exec_template_base = 'Store')
|
||||
mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore', exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
|
||||
def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{
|
||||
def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
|
||||
*flags) {{
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
|
||||
postacc_code, flags = flags, base_class = 'HwLoadStore')
|
||||
postacc_code, mem_flags = [], inst_flags = flags,
|
||||
base_class = 'HwLoadStore')
|
||||
}};
|
||||
|
||||
|
||||
|
|
|
@ -82,10 +82,9 @@ tokens = reserved + (
|
|||
|
||||
# ( ) [ ] { } < > , ; : :: *
|
||||
'LPAREN', 'RPAREN',
|
||||
# not used any more... commented out to suppress PLY warning
|
||||
# 'LBRACKET', 'RBRACKET',
|
||||
'LBRACKET', 'RBRACKET',
|
||||
'LBRACE', 'RBRACE',
|
||||
'LESS', 'GREATER',
|
||||
'LESS', 'GREATER', 'EQUALS',
|
||||
'COMMA', 'SEMI', 'COLON', 'DBLCOLON',
|
||||
'ASTERISK',
|
||||
|
||||
|
@ -104,13 +103,13 @@ tokens = reserved + (
|
|||
# Regular expressions for token matching
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
# not used any more... commented out to suppress PLY warning
|
||||
# t_LBRACKET = r'\['
|
||||
# t_RBRACKET = r'\]'
|
||||
t_LBRACKET = r'\['
|
||||
t_RBRACKET = r'\]'
|
||||
t_LBRACE = r'\{'
|
||||
t_RBRACE = r'\}'
|
||||
t_LESS = r'\<'
|
||||
t_GREATER = r'\>'
|
||||
t_EQUALS = r'='
|
||||
t_COMMA = r','
|
||||
t_SEMI = r';'
|
||||
t_COLON = r':'
|
||||
|
@ -387,32 +386,66 @@ def p_def_format(t):
|
|||
t[0] = GenCode()
|
||||
|
||||
# The formal parameter list for an instruction format is a possibly
|
||||
# empty list of comma-separated parameters.
|
||||
# empty list of comma-separated parameters. Positional (standard,
|
||||
# non-keyword) parameters must come first, followed by keyword
|
||||
# parameters, followed by a '*foo' parameter that gets excess
|
||||
# positional arguments (as in Python). Each of these three parameter
|
||||
# categories is optional.
|
||||
#
|
||||
# Note that we do not support the '**foo' parameter for collecting
|
||||
# otherwise undefined keyword args. Otherwise the parameter list is
|
||||
# (I believe) identical to what is supported in Python.
|
||||
#
|
||||
# The param list generates a tuple, where the first element is a list of
|
||||
# the positional params and the second element is a dict containing the
|
||||
# keyword params.
|
||||
def p_param_list_0(t):
|
||||
'param_list : empty'
|
||||
t[0] = [ ]
|
||||
'param_list : positional_param_list COMMA nonpositional_param_list'
|
||||
t[0] = t[1] + t[3]
|
||||
|
||||
def p_param_list_1(t):
|
||||
'param_list : param'
|
||||
'''param_list : positional_param_list
|
||||
| nonpositional_param_list'''
|
||||
t[0] = t[1]
|
||||
|
||||
def p_positional_param_list_0(t):
|
||||
'positional_param_list : empty'
|
||||
t[0] = []
|
||||
|
||||
def p_positional_param_list_1(t):
|
||||
'positional_param_list : ID'
|
||||
t[0] = [t[1]]
|
||||
|
||||
def p_param_list_2(t):
|
||||
'param_list : param_list COMMA param'
|
||||
t[0] = t[1]
|
||||
t[0].append(t[3])
|
||||
def p_positional_param_list_2(t):
|
||||
'positional_param_list : positional_param_list COMMA ID'
|
||||
t[0] = t[1] + [t[3]]
|
||||
|
||||
# Each formal parameter is either an identifier or an identifier
|
||||
# preceded by an asterisk. As in Python, the latter (if present) gets
|
||||
# a tuple containing all the excess positional arguments, allowing
|
||||
# varargs functions.
|
||||
def p_param_0(t):
|
||||
'param : ID'
|
||||
def p_nonpositional_param_list_0(t):
|
||||
'nonpositional_param_list : keyword_param_list COMMA excess_args_param'
|
||||
t[0] = t[1] + t[3]
|
||||
|
||||
def p_nonpositional_param_list_1(t):
|
||||
'''nonpositional_param_list : keyword_param_list
|
||||
| excess_args_param'''
|
||||
t[0] = t[1]
|
||||
|
||||
def p_param_1(t):
|
||||
'param : ASTERISK ID'
|
||||
# just concatenate them: '*ID'
|
||||
t[0] = t[1] + t[2]
|
||||
def p_keyword_param_list_0(t):
|
||||
'keyword_param_list : keyword_param'
|
||||
t[0] = [t[1]]
|
||||
|
||||
def p_keyword_param_list_1(t):
|
||||
'keyword_param_list : keyword_param_list COMMA keyword_param'
|
||||
t[0] = t[1] + [t[3]]
|
||||
|
||||
def p_keyword_param(t):
|
||||
'keyword_param : ID EQUALS expr'
|
||||
t[0] = t[1] + ' = ' + t[3].__repr__()
|
||||
|
||||
def p_excess_args_param(t):
|
||||
'excess_args_param : ASTERISK ID'
|
||||
# Just concatenate them: '*ID'. Wrap in list to be consistent
|
||||
# with positional_param_list and keyword_param_list.
|
||||
t[0] = [t[1] + t[2]]
|
||||
|
||||
# End of format definition-related rules.
|
||||
##############
|
||||
|
@ -577,26 +610,79 @@ def p_inst_1(t):
|
|||
codeObj.prepend_all(comment)
|
||||
t[0] = codeObj
|
||||
|
||||
# The arg list generates a tuple, where the first element is a list of
|
||||
# the positional args and the second element is a dict containing the
|
||||
# keyword args.
|
||||
def p_arg_list_0(t):
|
||||
'arg_list : empty'
|
||||
t[0] = [ ]
|
||||
'arg_list : positional_arg_list COMMA keyword_arg_list'
|
||||
t[0] = ( t[1], t[3] )
|
||||
|
||||
def p_arg_list_1(t):
|
||||
'arg_list : arg'
|
||||
t[0] = [t[1]]
|
||||
'arg_list : positional_arg_list'
|
||||
t[0] = ( t[1], {} )
|
||||
|
||||
def p_arg_list_2(t):
|
||||
'arg_list : arg_list COMMA arg'
|
||||
t[0] = t[1]
|
||||
t[0].append(t[3])
|
||||
'arg_list : keyword_arg_list'
|
||||
t[0] = ( [], t[1] )
|
||||
|
||||
def p_arg(t):
|
||||
'''arg : ID
|
||||
| INTLIT
|
||||
| STRLIT
|
||||
| CODELIT'''
|
||||
def p_positional_arg_list_0(t):
|
||||
'positional_arg_list : empty'
|
||||
t[0] = []
|
||||
|
||||
def p_positional_arg_list_1(t):
|
||||
'positional_arg_list : expr'
|
||||
t[0] = [t[1]]
|
||||
|
||||
def p_positional_arg_list_2(t):
|
||||
'positional_arg_list : positional_arg_list COMMA expr'
|
||||
t[0] = t[1] + [t[3]]
|
||||
|
||||
def p_keyword_arg_list_0(t):
|
||||
'keyword_arg_list : keyword_arg'
|
||||
t[0] = t[1]
|
||||
|
||||
def p_keyword_arg_list_1(t):
|
||||
'keyword_arg_list : keyword_arg_list COMMA keyword_arg'
|
||||
t[0] = t[1]
|
||||
t[0].update(t[3])
|
||||
|
||||
def p_keyword_arg(t):
|
||||
'keyword_arg : ID EQUALS expr'
|
||||
t[0] = { t[1] : t[3] }
|
||||
|
||||
#
|
||||
# Basic expressions. These constitute the argument values of
|
||||
# "function calls" (i.e. instruction definitions in the decode block)
|
||||
# and default values for formal parameters of format functions.
|
||||
#
|
||||
# Right now, these are either strings, integers, or (recursively)
|
||||
# lists of exprs (using Python square-bracket list syntax). Note that
|
||||
# bare identifiers are trated as string constants here (since there
|
||||
# isn't really a variable namespace to refer to).
|
||||
#
|
||||
def p_expr_0(t):
|
||||
'''expr : ID
|
||||
| INTLIT
|
||||
| STRLIT
|
||||
| CODELIT'''
|
||||
t[0] = t[1]
|
||||
|
||||
def p_expr_1(t):
|
||||
'''expr : LBRACKET list_expr RBRACKET'''
|
||||
t[0] = t[2]
|
||||
|
||||
def p_list_expr_0(t):
|
||||
'list_expr : expr'
|
||||
t[0] = [t[1]]
|
||||
|
||||
def p_list_expr_1(t):
|
||||
'list_expr : list_expr COMMA expr'
|
||||
t[0] = t[1] + [t[3]]
|
||||
|
||||
def p_list_expr_2(t):
|
||||
'list_expr : empty'
|
||||
t[0] = []
|
||||
|
||||
#
|
||||
# Empty production... use in other rules for readability.
|
||||
#
|
||||
|
@ -779,7 +865,7 @@ class Format:
|
|||
context.update(exportContext)
|
||||
context.update({ 'name': name, 'Name': string.capitalize(name) })
|
||||
try:
|
||||
vars = self.func(self.user_code, context, *args)
|
||||
vars = self.func(self.user_code, context, *args[0], **args[1])
|
||||
except Exception, exc:
|
||||
error(lineno, 'error defining "%s": %s.' % (name, exc))
|
||||
for k in vars.keys():
|
||||
|
@ -974,14 +1060,18 @@ class Template:
|
|||
#
|
||||
#####################################################################
|
||||
|
||||
# Force the argument to be a list
|
||||
def makeList(list_or_item):
|
||||
if not list_or_item:
|
||||
# Force the argument to be a list. Useful for flags, where a caller
|
||||
# can specify a singleton flag or a list of flags. Also usful for
|
||||
# converting tuples to lists so they can be modified.
|
||||
def makeList(arg):
|
||||
if isinstance(arg, list):
|
||||
return arg
|
||||
elif isinstance(arg, tuple):
|
||||
return list(arg)
|
||||
elif not arg:
|
||||
return []
|
||||
elif type(list_or_item) == ListType:
|
||||
return list_or_item
|
||||
else:
|
||||
return [ list_or_item ]
|
||||
return [ arg ]
|
||||
|
||||
# generate operandSizeMap based on provided operandTypeMap:
|
||||
# basically generate equiv. C++ type and make is_signed flag
|
||||
|
@ -1253,7 +1343,7 @@ class NPCOperandTraits(OperandTraits):
|
|||
exportContextSymbols = ('IntRegOperandTraits', 'FloatRegOperandTraits',
|
||||
'ControlRegOperandTraits', 'MemOperandTraits',
|
||||
'NPCOperandTraits', 'InstObjParams', 'CodeBlock',
|
||||
're', 'string')
|
||||
'makeList', 're', 'string')
|
||||
|
||||
exportContext = {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue