Sfoglia il codice sorgente

+ ifdef USE_OP3 code :
added all missing op_... constructors for tai386 needed
for SHRD,SHLD and IMUL code in assembler readers
(check in tests/tbs0123.pp)

pierre 26 anni fa
parent
commit
e39755387b
5 ha cambiato i file con 491 aggiunte e 55 eliminazioni
  1. 14 1
      compiler/ag386int.pas
  2. 16 3
      compiler/ag386nsm.pas
  3. 70 1
      compiler/i386.pas
  4. 237 6
      compiler/ra386att.pas
  5. 154 44
      compiler/ra386int.pas

+ 14 - 1
compiler/ag386int.pas

@@ -663,10 +663,17 @@ ait_labeled_instruction : AsmWriteLn(#9#9+int_op2str[pai386_labeled(hp)^.opcode]
                              if pai386(hp)^.op3t<>top_none then
                               begin
                                 if pai386(hp)^.op2t<>top_none then
+{$ifndef USE_OP3}
                                  s:=getopstr(pai386(hp)^.op2t,pointer(longint(twowords(pai386(hp)^.op2).word1)),0,
                                              pai386(hp)^.opsize,pai386(hp)^.opcode,true)+','+s;
                                 s:=getopstr(pai386(hp)^.op3t,pointer(longint(twowords(pai386(hp)^.op2).word2)),0,
                                             pai386(hp)^.opsize,pai386(hp)^.opcode,false)+','+s;
+{$else USE_OP3}
+                                 s:=getopstr(pai386(hp)^.op2t,pai386(hp)^.op2,0,
+                                             pai386(hp)^.opsize,pai386(hp)^.opcode,true)+','+s;
+                                s:=getopstr(pai386(hp)^.op3t,pai386(hp)^.op3,0,
+                                            pai386(hp)^.opsize,pai386(hp)^.opcode,false)+','+s;
+{$endif USE_OP3}
                               end
                              else
                               if pai386(hp)^.op2t<>top_none then
@@ -788,7 +795,13 @@ ait_stab_function_name : ;
 end.
 {
   $Log$
-  Revision 1.30  1999-03-29 16:05:43  peter
+  Revision 1.31  1999-04-16 10:00:55  pierre
+    + ifdef USE_OP3 code :
+      added all missing op_... constructors for tai386 needed
+      for SHRD,SHLD and IMUL code in assembler readers
+      (check in tests/tbs0123.pp)
+
+  Revision 1.30  1999/03/29 16:05:43  peter
     * optimizer working for ag386bin
 
   Revision 1.29  1999/03/02 02:56:10  peter

+ 16 - 3
compiler/ag386nsm.pas

@@ -621,10 +621,17 @@ ait_labeled_instruction :
                              if pai386(hp)^.op3t<>top_none then
                               begin
                                 if pai386(hp)^.op2t<>top_none then
+{$ifndef USE_OP3}
                                  s:=getopstr(pai386(hp)^.op2t,pointer(longint(twowords(pai386(hp)^.op2).word1)),0,
                                              pai386(hp)^.opsize,pai386(hp)^.opcode,true)+','+s;
-                                          s:=getopstr(pai386(hp)^.op3t,pointer(longint(twowords(pai386(hp)^.op2).word2)),0,
-                                           pai386(hp)^.opsize,pai386(hp)^.opcode,false)+','+s;
+                                s:=getopstr(pai386(hp)^.op3t,pointer(longint(twowords(pai386(hp)^.op2).word2)),0,
+                                            pai386(hp)^.opsize,pai386(hp)^.opcode,false)+','+s;
+{$else USE_OP3}
+                                 s:=getopstr(pai386(hp)^.op2t,pai386(hp)^.op2,0,
+                                             pai386(hp)^.opsize,pai386(hp)^.opcode,true)+','+s;
+                                s:=getopstr(pai386(hp)^.op3t,pai386(hp)^.op3,0,
+                                            pai386(hp)^.opsize,pai386(hp)^.opcode,false)+','+s;
+{$endif USE_OP3}
                               end
                              else
                               if pai386(hp)^.op2t<>top_none then
@@ -733,7 +740,13 @@ ait_stab_function_name : ;
 end.
 {
   $Log$
-  Revision 1.25  1999-03-29 16:05:44  peter
+  Revision 1.26  1999-04-16 10:00:56  pierre
+    + ifdef USE_OP3 code :
+      added all missing op_... constructors for tai386 needed
+      for SHRD,SHLD and IMUL code in assembler readers
+      (check in tests/tbs0123.pp)
+
+  Revision 1.25  1999/03/29 16:05:44  peter
     * optimizer working for ag386bin
 
   Revision 1.24  1999/03/10 13:25:44  pierre

+ 70 - 1
compiler/i386.pas

@@ -402,6 +402,9 @@ unit i386;
           opxt:word;
           op1,op2 : pointer;
           op1ofs : longint;
+{$ifdef USE_OP3}
+          op3 : pointer;
+{$endif USE_OP3}
           constructor op_none(op : tasmop;_size : topsize);
 
           constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
@@ -429,6 +432,12 @@ unit i386;
 
           constructor op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : tregister);
 
+{$ifdef USE_OP3}
+          constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
+          constructor op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
+          constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : tregister;_op3 : preference);
+{$endif USE_OP3}
+
           { this is for CALL etc.                            }
           { symbol is replaced by the address of symbol      }
           { so op_csymbol(A_PUSH,S_L,strnew('P')); generates }
@@ -1512,10 +1521,12 @@ unit i386;
 
       end;
 
+{$ifndef USE_OP3}
     type
        twowords=record
           word1,word2:word;
        end;
+{$endif ndef USE_OP3}
 
     constructor tai386.op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
 
@@ -1526,8 +1537,13 @@ unit i386;
          opxt:=Top_reg shl 8+Top_reg shl 4+Top_reg;
          opsize:=_size;
          op1:=pointer(_op1);
+{$ifndef USE_OP3}
          twowords(op2).word1:=word(_op2);
          twowords(op2).word2:=word(_op3);
+{$else USE_OP3}
+         op2:=pointer(_op2);
+         op3:=pointer(_op3);
+{$endif USE_OP3}
       end;
 
     constructor tai386.op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : preference);
@@ -1621,10 +1637,57 @@ unit i386;
          opxt:=Top_const+Top_reg shl 4+Top_reg shl 8;
          opsize:=_size;
          op1:=pointer(_op1);
+{$ifndef USE_OP3}
          twowords(op2).word1:=word(_op2);
          twowords(op2).word2:=word(_op3);
+{$else USE_OP3}
+         op2:=pointer(_op2);
+         op3:=pointer(_op3);
+{$endif USE_OP3}
+      end;
+
+{$ifdef USE_OP3}
+    constructor tai386.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
+
+      begin
+         inherited init;
+         typ:=ait_instruction;
+         opcode:=op;
+         opxt:=Top_const+Top_reg shl 4+Top_ref shl 8;
+         opsize:=_size;
+         op1:=pointer(_op1);
+         op2:=pointer(_op2);
+         op3:=pointer(_op3);
       end;
 
+    constructor tai386.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
+
+      begin
+         inherited init;
+         typ:=ait_instruction;
+         opcode:=op;
+         opxt:=Top_const+Top_ref shl 4+Top_reg shl 8;
+         opsize:=_size;
+         op1:=pointer(_op1);
+         op2:=pointer(_op2);
+         op3:=pointer(_op3);
+      end;
+
+    constructor tai386.op_reg_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : tregister;_op3 : preference);
+
+      begin
+         inherited init;
+         typ:=ait_instruction;
+         opcode:=op;
+         opxt:=Top_reg+Top_reg shl 4+Top_ref shl 8;
+         opsize:=_size;
+         op1:=pointer(_op1);
+         op2:=pointer(_op2);
+         op3:=pointer(_op3);
+      end;
+{$endif USE_OP3}
+
+
     constructor tai386.op_const_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister);
 
       begin
@@ -1978,7 +2041,13 @@ Begin
 end.
 {
   $Log$
-  Revision 1.39  1999-04-12 19:20:45  florian
+  Revision 1.40  1999-04-16 10:00:57  pierre
+    + ifdef USE_OP3 code :
+      added all missing op_... constructors for tai386 needed
+      for SHRD,SHLD and IMUL code in assembler readers
+      (check in tests/tbs0123.pp)
+
+  Revision 1.39  1999/04/12 19:20:45  florian
     * iret is in intel mode now written as iretd
 
   Revision 1.38  1999/03/26 00:05:31  peter

+ 237 - 6
compiler/ra386att.pas

@@ -1456,6 +1456,26 @@ var
                 exit;
               end;
           end;
+      A_IMUL:
+       { these instruction are fully parsed individually on pass three }
+       { so we just do a summary checking here.                        }
+       Begin
+         if numops = 3 then
+           Begin
+             if (operands[1].operandtype = OPR_CONSTANT) and
+                (operands[1].val <= 127) and (operands[1].val >=-128) then
+               Begin
+                 operands[1].opinfo := ao_imm8s;
+                 operands[1].size := S_B;
+               end
+             else
+               Begin
+                 { should depend on size of other operands !! }
+                 operands[1].opinfo := ao_imm32;
+                 operands[1].size := S_L;
+               End
+           end;
+       end;
         A_INT:
           Begin
             if numops = 1 then
@@ -2038,6 +2058,203 @@ var
                end; {end else of case instruc of movsx ... }
            end; { end case movsx ...}
         end;
+     3: Begin
+             { only imul, shld and shrd  }
+             { middle must be a register }
+             if ((instruc = A_SHLD) or (instruc = A_SHRD)) and (instr.operands[2].operandtype =
+                OPR_REGISTER) then
+              Begin
+               case instr.operands[2].size of
+                S_W:
+                 if instr.operands[1].operandtype = OPR_CONSTANT then
+                  Begin
+                   if instr.operands[1].val <= $ff then
+                    Begin
+                     if instr.operands[3].size in [S_NO,S_W] then
+                      Begin
+                       case instr.operands[3].operandtype of
+                        OPR_REFERENCE:
+{$ifdef USE_OP3}
+                         p^.concat(new(pai386,
+                          op_const_reg_ref(instruc, S_W,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          newreference(instr.operands[3].ref))));
+{$else USE_OP3}
+                         Message(assem_e_unsupported_opcode_and_operand)
+                         { MISSING !!!! } ;
+{$endif USE_OP3}
+                        OPR_REGISTER:
+                         p^.concat(new(pai386,
+                          op_const_reg_reg(instruc, S_W,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          instr.operands[3].reg)));
+                        else
+                         Message(assem_e_invalid_opcode_and_operand);
+                        end;
+                       end
+                      else
+                       Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+                 else if instr.operands[1].operandtype = OPR_REGISTER then
+{$ifndef USE_OP3}
+                   Message(assem_e_unsupported_opcode_and_operand)
+{$else USE_OP3}
+                  begin
+                   case instr.operands[3].operandtype of
+                    OPR_REFERENCE:
+                     p^.concat(new(pai386,
+                      op_reg_reg_ref(instruc, S_W,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      newreference(instr.operands[3].ref))));
+                    OPR_REGISTER:
+                     p^.concat(new(pai386,
+                      op_reg_reg_reg(instruc, S_W,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      instr.operands[3].reg)));
+                    else
+                     Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+{$endif USE_OP3}
+                 else
+                  Message(assem_e_invalid_opcode_and_operand);
+                S_L:
+                 if instr.operands[1].operandtype = OPR_CONSTANT then
+                  Begin
+                   if instr.operands[1].val <= $ff then
+                    Begin
+                     if instr.operands[3].size in [S_NO,S_L] then
+                      Begin
+                       case instr.operands[3].operandtype of
+                        OPR_REFERENCE:
+{$ifdef USE_OP3}
+                         p^.concat(new(pai386,
+                          op_const_reg_ref(instruc, S_L,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          newreference(instr.operands[3].ref))));
+{$else USE_OP3}
+                         Message(assem_e_unsupported_opcode_and_operand)
+                         { MISSING !!!! } ;
+{$endif USE_OP3}
+                        OPR_REGISTER:
+                         p^.concat(new(pai386,
+                           op_const_reg_reg(instruc, S_L,
+                           instr.operands[1].val, instr.operands[2].reg,
+                           instr.operands[3].reg)));
+                       else
+                        Message(assem_e_invalid_opcode_and_operand);
+                      end;
+                    end
+                   else
+                    Message(assem_e_invalid_opcode_and_operand);
+                  end;
+                 end
+                 else if instr.operands[1].operandtype = OPR_REGISTER then
+{$ifndef USE_OP3}
+                   Message(assem_e_unsupported_opcode_and_operand)
+{$else USE_OP3}
+                  begin
+                   case instr.operands[3].operandtype of
+                    OPR_REFERENCE:
+                     p^.concat(new(pai386,
+                      op_reg_reg_ref(instruc, S_L,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      newreference(instr.operands[3].ref))));
+                    OPR_REGISTER:
+                     p^.concat(new(pai386,
+                      op_reg_reg_reg(instruc, S_L,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      instr.operands[3].reg)));
+                    else
+                     Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+{$endif USE_OP3}
+                else
+                    Message(assem_e_invalid_opcode_and_operand);
+                { else of case instr.operands[2].size of }
+                else
+                  Message(assem_e_invalid_opcode_and_operand);
+               end; { end case }
+              end
+             else
+              if (instruc = A_IMUL) and
+                (instr.operands[3].operandtype = OPR_REGISTER) then
+               Begin
+                case instr.operands[3].size of
+                 S_W:  if instr.operands[1].operandtype = OPR_CONSTANT then
+                        Begin
+                          if instr.operands[1].val <= $ffff then
+                            Begin
+                              if instr.operands[2].size in [S_NO,S_W] then
+                              Begin
+                                 case instr.operands[2].operandtype of
+                                  OPR_REFERENCE:
+{$ifdef USE_OP3}
+                                   p^.concat(new(pai386,
+                                     op_const_ref_reg(instruc, S_W,
+                                       instr.operands[1].val, newreference(instr.operands[2].ref),
+                                       instr.operands[3].reg)));
+{$else USE_OP3}
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
+{$endif USE_OP3}
+                                  OPR_REGISTER:  p^.concat(new(pai386,
+                                     op_const_reg_reg(instruc, S_W,
+                                     instr.operands[1].val, instr.operands[2].reg,
+                                     instr.operands[3].reg)));
+                                 else
+                                  Message(assem_e_invalid_opcode_and_operand);
+                                 end; { end case }
+                              end
+                              else
+                                Message(assem_e_invalid_opcode_and_operand);
+                            end;
+                        end
+                      else
+                        Message(assem_e_invalid_opcode_and_operand);
+                S_L:  if instr.operands[1].operandtype = OPR_CONSTANT then
+                        Begin
+                          if instr.operands[1].val <= $7fffffff then
+                            Begin
+                              if instr.operands[2].size in [S_NO,S_L] then
+                              Begin
+                                 case instr.operands[2].operandtype of
+                                  OPR_REFERENCE:
+{$ifdef USE_OP3}
+                                   p^.concat(new(pai386,
+                                     op_const_ref_reg(instruc, S_L,
+                                       instr.operands[1].val, newreference(instr.operands[2].ref),
+                                       instr.operands[3].reg)));
+{$else USE_OP3}
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
+{$endif USE_OP3}
+                                  OPR_REGISTER:  p^.concat(new(pai386,
+                                     op_const_reg_reg(instruc, S_L,
+                                     instr.operands[1].val, instr.operands[2].reg,
+                                     instr.operands[3].reg)));
+                                 else
+                                   Message(assem_e_invalid_opcode_and_operand);
+                                 end; { end case }
+                              end
+                              else
+                               Message(assem_e_invalid_opcode_and_operand);
+                            end;
+                        end
+                      else
+                       Message(assem_e_invalid_opcode_and_operand);
+                else
+                  Message(assem_e_invalid_middle_sized_operand);
+                end; { end case }
+               end { endif }
+             else
+               Message(assem_e_invalid_three_operand_opcode);
+        end;
+(*   Old code not yet removed because I did not check exactly that there
+     was no difference between ra386int and ra386att code
+     The code above is just a copy of the code from ra386int ! (PM)
      3: Begin
              { only imul, shld and shrd  }
              { middle must be a register }
@@ -2052,7 +2269,9 @@ var
                               if instr.operands[3].size in [S_W] then
                               Begin
                                  case instr.operands[3].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_W,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -2074,7 +2293,9 @@ var
                               if instr.operands[3].size in [S_L] then
                               Begin
                                  case instr.operands[3].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_L,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -2105,7 +2326,9 @@ var
                               if instr.operands[2].size in [S_W] then
                               Begin
                                  case instr.operands[2].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_W,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -2127,7 +2350,9 @@ var
                               if instr.operands[2].size in [S_L] then
                               Begin
                                  case instr.operands[2].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_L,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -2148,7 +2373,7 @@ var
              end { endif }
            else
              Message(assem_e_invalid_three_operand_opcode);
-        end;
+        end; *)
   end; { end case }
  end;
  end;
@@ -3692,7 +3917,13 @@ end.
 
 {
   $Log$
-  Revision 1.33  1999-02-25 21:02:47  peter
+  Revision 1.34  1999-04-16 10:00:58  pierre
+    + ifdef USE_OP3 code :
+      added all missing op_... constructors for tai386 needed
+      for SHRD,SHLD and IMUL code in assembler readers
+      (check in tests/tbs0123.pp)
+
+  Revision 1.33  1999/02/25 21:02:47  peter
     * ag386bin updates
     + coff writer
 

+ 154 - 44
compiler/ra386int.pas

@@ -1203,6 +1203,26 @@ var
              exit;
            end;
        end;
+      A_IMUL:
+       { these instruction are fully parsed individually on pass three }
+       { so we just do a summary checking here.                        }
+       Begin
+         if numops = 3 then
+           Begin
+             if (operands[3].operandtype = OPR_CONSTANT) and
+                (operands[3].val <= 127) and (operands[3].val >=-128) then
+               Begin
+                 operands[3].opinfo := ao_imm8s;
+                 operands[3].size := S_B;
+               end
+             else
+               Begin
+                 { should depend on size of other operands !! }
+                 operands[3].opinfo := ao_imm32;
+                 operands[3].size := S_L;
+               End
+           end;
+       end;
       A_INT:
        Begin
          if numops = 1 then
@@ -1659,49 +1679,115 @@ var
                 OPR_REGISTER) then
               Begin
                case instr.operands[2].size of
-                S_W:  if instr.operands[1].operandtype = OPR_CONSTANT then
-                        Begin
-                          if instr.operands[1].val <= $ff then
-                            Begin
-                              if instr.operands[3].size in [S_W] then
-                              Begin
-                                 case instr.operands[3].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
-                                  OPR_REGISTER:  p^.concat(new(pai386,
-                                     op_const_reg_reg(instruc, S_W,
-                                     instr.operands[1].val, instr.operands[2].reg,
-                                     instr.operands[3].reg)));
-                                 else
-                                    Message(assem_e_invalid_opcode_and_operand);
-                                    Message(assem_e_invalid_opcode_and_operand);
-                                 end;
-                              end
-                              else
-                                 Message(assem_e_invalid_opcode_and_operand);
-                            end;
-                        end
+                S_W:
+                 if instr.operands[1].operandtype = OPR_CONSTANT then
+                  Begin
+                   if instr.operands[1].val <= $ff then
+                    Begin
+                     if instr.operands[3].size in [S_W] then
+                      Begin
+                       case instr.operands[3].operandtype of
+                        OPR_REFERENCE:
+{$ifdef USE_OP3}
+                         p^.concat(new(pai386,
+                          op_const_reg_ref(instruc, S_W,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          newreference(instr.operands[3].ref))));
+{$else USE_OP3}
+                         Message(assem_e_unsupported_opcode_and_operand)
+                         { MISSING !!!! } ;
+{$endif USE_OP3}
+                        OPR_REGISTER:
+                         p^.concat(new(pai386,
+                          op_const_reg_reg(instruc, S_W,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          instr.operands[3].reg)));
+                        else
+                         Message(assem_e_invalid_opcode_and_operand);
+                        end;
+                       end
                       else
+                       Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+                 else if instr.operands[1].operandtype = OPR_REGISTER then
+{$ifndef USE_OP3}
+                   Message(assem_e_unsupported_opcode_and_operand)
+{$else USE_OP3}
+                  begin
+                   case instr.operands[3].operandtype of
+                    OPR_REFERENCE:
+                     p^.concat(new(pai386,
+                      op_reg_reg_ref(instruc, S_W,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      newreference(instr.operands[3].ref))));
+                    OPR_REGISTER:
+                     p^.concat(new(pai386,
+                      op_reg_reg_reg(instruc, S_W,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      instr.operands[3].reg)));
+                    else
+                     Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+{$endif USE_OP3}
+                 else
+                  Message(assem_e_invalid_opcode_and_operand);
+                S_L:
+                 if instr.operands[1].operandtype = OPR_CONSTANT then
+                  Begin
+                   if instr.operands[1].val <= $ff then
+                    Begin
+                     if instr.operands[3].size in [S_L] then
+                      Begin
+                       case instr.operands[3].operandtype of
+                        OPR_REFERENCE:
+{$ifdef USE_OP3}
+                         p^.concat(new(pai386,
+                          op_const_reg_ref(instruc, S_L,
+                          instr.operands[1].val, instr.operands[2].reg,
+                          newreference(instr.operands[3].ref))));
+{$else USE_OP3}
+                         Message(assem_e_unsupported_opcode_and_operand)
+                         { MISSING !!!! } ;
+{$endif USE_OP3}
+                        OPR_REGISTER:
+                         p^.concat(new(pai386,
+                           op_const_reg_reg(instruc, S_L,
+                           instr.operands[1].val, instr.operands[2].reg,
+                           instr.operands[3].reg)));
+                       else
                         Message(assem_e_invalid_opcode_and_operand);
-                S_L:  if instr.operands[1].operandtype = OPR_CONSTANT then
-                        Begin
-                          if instr.operands[1].val <= $ff then
-                            Begin
-                              if instr.operands[3].size in [S_L] then
-                              Begin
-                                 case instr.operands[3].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
-                                  OPR_REGISTER:  p^.concat(new(pai386,
-                                     op_const_reg_reg(instruc, S_L,
-                                     instr.operands[1].val, instr.operands[2].reg,
-                                     instr.operands[3].reg)));
-                                 else
-                                   Message(assem_e_invalid_opcode_and_operand);
-                                 end;
-                              end
-                              else
-                                Message(assem_e_invalid_opcode_and_operand);
-                            end;
-                        end;
+                      end;
+                    end
+                   else
+                    Message(assem_e_invalid_opcode_and_operand);
+                  end;
+                 end
+                 else if instr.operands[1].operandtype = OPR_REGISTER then
+{$ifndef USE_OP3}
+                   Message(assem_e_unsupported_opcode_and_operand)
+{$else USE_OP3}
+                  begin
+                   case instr.operands[3].operandtype of
+                    OPR_REFERENCE:
+                     p^.concat(new(pai386,
+                      op_reg_reg_ref(instruc, S_L,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      newreference(instr.operands[3].ref))));
+                    OPR_REGISTER:
+                     p^.concat(new(pai386,
+                      op_reg_reg_reg(instruc, S_L,
+                      instr.operands[1].reg, instr.operands[2].reg,
+                      instr.operands[3].reg)));
+                    else
+                     Message(assem_e_invalid_opcode_and_operand);
+                    end;
+                  end
+{$endif USE_OP3}
+                else
+                    Message(assem_e_invalid_opcode_and_operand);
+                { else of case instr.operands[2].size of }
                 else
                   Message(assem_e_invalid_opcode_and_operand);
                end; { end case }
@@ -1718,7 +1804,16 @@ var
                               if instr.operands[2].size in [S_W] then
                               Begin
                                  case instr.operands[2].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+{$ifdef USE_OP3}
+                                   p^.concat(new(pai386,
+                                     op_const_ref_reg(instruc, S_W,
+                                       instr.operands[1].val, newreference(instr.operands[2].ref),
+                                       instr.operands[3].reg)));
+{$else USE_OP3}
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
+{$endif USE_OP3}
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_W,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -1740,7 +1835,16 @@ var
                               if instr.operands[2].size in [S_L] then
                               Begin
                                  case instr.operands[2].operandtype of
-                                  OPR_REFERENCE: { MISSING !!!! } ;
+                                  OPR_REFERENCE:
+{$ifdef USE_OP3}
+                                   p^.concat(new(pai386,
+                                     op_const_ref_reg(instruc, S_L,
+                                       instr.operands[1].val, newreference(instr.operands[2].ref),
+                                       instr.operands[3].reg)));
+{$else USE_OP3}
+                                   Message(assem_e_unsupported_opcode_and_operand)
+                                   { MISSING !!!! } ;
+{$endif USE_OP3}
                                   OPR_REGISTER:  p^.concat(new(pai386,
                                      op_const_reg_reg(instruc, S_L,
                                      instr.operands[1].val, instr.operands[2].reg,
@@ -3480,7 +3584,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.25  1999-04-14 09:14:56  peter
+  Revision 1.26  1999-04-16 10:01:00  pierre
+    + ifdef USE_OP3 code :
+      added all missing op_... constructors for tai386 needed
+      for SHRD,SHLD and IMUL code in assembler readers
+      (check in tests/tbs0123.pp)
+
+  Revision 1.25  1999/04/14 09:14:56  peter
     * first things to store the symbol/def number in the ppu
 
   Revision 1.24  1999/03/26 00:05:41  peter