예제 #1
0
def parse_one_operand(w, 
                      default_vis='DEFAULT', 
                      xtypes=None, 
                      default_xtypes=None,
                      internal=False):
   """Format examples:
   name=xxxxxy:{r,w,crw,rw,rcw}[:{EXPL,IMPL,SUPP,ECOND}][:{some oc2 code}][:{some xtype code}]
   name=NTLUR():{r,w,crw,rw,rcw}[:{EXPL,IMPL,SUPP,ECOND}][:{some oc2 code}][:{some xtype code}]
          oc2 can be before EXPL/IMPL/SUPP. oc2 is the width code.
          MEM{0,1}, PTR, RELBR, AGEN, IMM{0,1,2,3}

          xtype describes the number of data type and width of each element.
          If the xtype is omitted, xed will attempt to infer it from the oc2 code.

          ECOND is for encoder-only conditions. Completely ignored by the decoder.
          
   Default is read-only

   @param w: string
   @param w: an operand specification string
   
   @rtype operand_info_t
   @return a parsed operand
   """
   
   if vopnd():
      genutil.msge("PARSE-OPND: " + w)

   # get the r/w/rw info, if any
   vis = default_vis
   oc2 = None
   otype = None
   rw = 'r'
   cvt = []
   invert = False
   lookupfn_name=None
   xtype = None
   multireg = 0
   if colon_pattern.search(w):
      chunks = w.split(':')
      if vopnd():
         genutil.msge("CHUNKS [%s]" % (",".join(chunks)))
      for i,c in enumerate(chunks):
         if vopnd():
            genutil.msge("\tCHUNK %d %s" %( i,c))
         if i == 0:
            a = c
         elif i == 1:
            rw = c
            if vopnd():
               genutil.msge("\t\tSET rw to  %s" % (rw))
         elif (i == 2 or i == 3) and (c in ['IMPL', 'SUPP',  'EXPL', 'ECOND']):
            vis = c
            if vopnd():
               genutil.msge("\t\tSET VIS to %s" % (vis))
         else: # FIXME: somewhat sloppy error checking on input
                      
            multi_reg_p=multireg_pattern.match(c)
            cp=convert_pattern.match(c)
            
            if multi_reg_p:
                multireg = int(multi_reg_p.group('nreg')) 
            elif cp:
                cvt.append(cp.group('rhs'))
            elif oc2 == None and oc2_pattern.match(c):
               oc2 = c
               if vopnd():
                  genutil.msge("\t\tSET OC2 to  %s" % (oc2))
            elif oc2 and c in xtypes:
               xtype = c
               if vopnd():
                  genutil.msge("\t\tSET xtype to  %s" % (xtype))
            elif decimal_number_pattern.match(c):
               genutil.die("Bad number in %s" % (w))
            else:
               genutil.die(
                   "Bad oc2 pattern in %s when looking at %d chunk: %s " %
                   (w,i,c) )

   else:
      a = w
      
   if vis == 'ECOND':
      return None
   
      
   # From now on, use a, not w.

   if slash_pattern.search(a):
      genutil.die("Bad slash in operand")

   if xtype == None:
      # need to use the default xtype based on the oc2 width code
      if oc2:
         try:
            xtype = default_xtypes[oc2.upper()]
         except:
            s = ''
            for i,v in default_xtypes.items():
               s += "\t%10s -> %10s\n" % (i,v)
            genutil.die("Parsing operand [%s]. Could not find default type for %s. xtypes=%s\nTypes=%s" % (w, oc2, str(xtypes), s))
      else:
         # there was no oc2 type and no xtype. probably a nonterminal
         # lookup function
         xtype = 'INVALID'

   # look for X=y and X!=y and bare operands like MEM0.

   eqp = equals_pattern.search(a)
   neqp = not_equals_pattern.search(a)
   if eqp:
      (name,rhs)  = eqp.group('lhs','rhs')
      if vopnd():
         genutil.msge("PARSE-OPND:\t" + name + " + " + rhs)
      
      if double_parens_pattern.search(rhs): # NTLUF
         if vopnd():
            genutil.msge("PARSE-OPND:\t nonterminal lookup function "
                 + name + " <- " + rhs)
         # remove the parens
         nt_lookup_fn = double_parens_pattern.sub('',rhs)         
         optype ='nt_lookup_fn'
         rhs = None
         lookupfn_name=nt_lookup_fn
     
      elif reg_pattern.match(rhs):
         optype = 'reg'
      elif error_pattern.match(rhs):
         optype = 'error'
      elif enum_pattern.match(rhs): 
         # for storing XED_* enum values as RHS's of operand bindings
         optype = 'imm_const'
      elif (not genutil.numeric(rhs)) and az_cap_pattern.search(rhs): 
         genutil.die("THIS SHOULD NOT HAPPEN: %s" % (rhs))
      elif letters_underscore_pattern.match(rhs):   
         rhs = list(rhs.replace('_',''))
         optype = 'imm'
      else:
         rhs = hex(genutil.make_numeric(rhs))
         optype = 'imm_const'
   elif neqp:
      (name,rhs)  = neqp.group('lhs','rhs')
      if vopnd():
         genutil.msge("PARSE-OPND: (NOT EQUALS)\t" + name + " + " + rhs)
      invert = True
      if reg_pattern.match(rhs):
         optype = 'reg'
      elif az_cap_pattern.search(rhs): 
          genutil.die("THIS SHOULD NOT HAPPEN")
      elif letters_underscore_pattern.match(rhs): 
          genutil.die("Cannot have a != pattern with don't-care letters")
      else:
          rhs = hex(genutil.make_numeric(rhs))
          optype = 'imm_const'
   elif mem_pattern.search(a):        # memop
      name = a
      optype ='imm_const'
      rhs = '1'
   elif imm_token_pattern.search(a):        # immediate placeholder
      name = a
      optype ='imm_const'
      rhs = '1'
   elif agen_pattern.search(a):        # agen
      name = a
      optype ='imm_const'
      rhs = '1'
   elif relative_branch_pattern.search(a):
      name = a
      optype ='imm_const'
      rhs = '1'
   elif pointer_pattern.search(a): 
      name = a
      optype ='imm_const'
      rhs = '1'
   elif xed_reset_pattern.search(a):
      # special marker that tells the traverser to restart this
      # nonterminal from the current position
      name = a
      optype ='xed_reset'
      rhs = ''
      vis = 'SUPP'
   elif double_parens_pattern.search(a):
      if vopnd():
         genutil.msge("PARSE-OPND:\t unbound nonterminal lookup function " +
                      a)
      # 2007-07-23 this code is not used
      genutil.die("UNBOUND NTLUF!: %s" % (a)) 
               
   else:
      # macros -- these get rewritten later
      if vopnd():
         genutil.msge("PARSE-OPND:\t flag-ish: " + a)
      name = a
      optype = 'flag'
      rhs = ''

   
   xop =  operand_info_t(name, optype, rhs, rw=rw, invert=invert,
                         vis=vis, oc2=oc2, cvt=cvt, xtype=xtype,
                         lookupfn_name=lookupfn_name, internal=internal,
                         multireg=multireg)

   return xop
예제 #2
0
 def dump(self, pad=''):
    genutil.msge( self.dump_str(pad))