Page 2 of 2

issue-#204 SYSTEM.BIT bug

Posted: Sat Nov 23, 2019 11:44 am
by luowy
do you mean?

Code: Select all

		PROCEDURE Bit (op: INTEGER);
			VAR reg, base, inx, d: INTEGER; scale, mode: SHORTINT; disp: INTEGER;
		BEGIN
			w := 1;
			ModRm(mode, reg, base, inx, scale, disp);
			 
			IF op = 0A3H THEN
				WriteOp("bt"); 
			ELSIF op = 0ABH THEN
				WriteOp("bts");  
			ELSIF op = 0B3H THEN
				WriteOp("btr");  
			ELSIF op = 0BBH THEN
				WriteOp("btc");  
			
			ELSIF op = 0BCH THEN
				WriteOp("bsf");   
			ELSE(* 0BDH *)
				WriteOp("bsr");  
			END;
			IF mode = Reg THEN 
				d:=1; IF (op = 0BCH) OR (op = 0BDH) THEN d:=0 END;
				WriteRM(Reg, d, base, reg, none, 0, 0, 0, FALSE)
			ELSE 
				d:=0; IF (op = 0BCH) OR (op = 0BDH) THEN d:=1 END;
				WriteRM(mode, d, reg, base, inx, scale, disp, 0, FALSE)
			END
		END Bit; 
anyway, my test code here:

Code: Select all

MODULE TestSystemBit;

	IMPORT Log := StdLog, S := SYSTEM;
	
(*		
			IF op = 0A3H THEN
				WriteOp("bt"); 
			ELSIF op = 0ABH THEN
				WriteOp("bts");  
			ELSIF op = 0B3H THEN
				WriteOp("btr");  
			ELSIF op = 0BBH THEN
				WriteOp("btc");  
				
			ELSIF op = 0BCH THEN
				WriteOp("bsf");  
			ELSE
				WriteOp("bsr");  
			END;
 *)
		 
		
	(* bt *)
	
	PROCEDURE [code] bt_regimm()
		0FH, 0BAH, 0E0H, 03H;    (* BT	EAX, 3 *)
	
	PROCEDURE [code] bt_memimm()
		0FH, 0BAH, 020H, 03H;	(* BT	DWORD[EAX], 3*)

	PROCEDURE [code] bt_regreg()
		0FH, 0A3H, 0D0H;	      (*BT	EAX, EDX*)		
		
	PROCEDURE [code] bt_memreg()
		0FH, 0A3H, 010H;	      (*BT	[EAX], EDX *)	
		
	PROCEDURE bt();
	BEGIN
		bt_regimm;
		bt_memimm;
		bt_regreg;
		bt_memreg
	END bt;
		
	(* bts*)	
	PROCEDURE [code] bts_regimm()
		0FH, 0BAH, 0E8H, 03H;    (* BTS	EAX, 3 *)
	
	PROCEDURE [code] bts_memimm()
		0FH, 0BAH, 028H, 03H;	 (* BTS	[EAX], 3*)

	PROCEDURE [code] bts_regreg()
		0FH, 0ABH, 0D0H;	       (*BTS	EAX, EDX*)		
		
	PROCEDURE [code] bts_memreg()
		0FH, 0ABH, 010H;	       (*BTS	[EAX], EDX *)	
		
		
	PROCEDURE bts();
	BEGIN
		bts_regimm;
		bts_memimm;
		bts_regreg;
		bts_memreg
	END bts;
	
	(* btr*)
	PROCEDURE [code] btr_regimm()
		0FH, 0BAH, 0F0H, 03H;    (* BTR	EAX, 3 *)
	
	PROCEDURE [code] btr_memimm()
		0FH, 0BAH, 030H, 03H;	 (* BTR	[EAX], 3*)

	PROCEDURE [code] btr_regreg()
		0FH, 0B3H, 0D0H;	       (*BTR	EAX, EDX*)		
		
	PROCEDURE [code] btr_memreg()
		0FH, 0B3H, 010H;	       (*BTR	[EAX], EDX *)	
	
	
	PROCEDURE btr();
	BEGIN
		btr_regimm;
		btr_memimm;
		btr_regreg;
		btr_memreg
	END btr;	
	
	(* btc*)
	PROCEDURE [code] btc_regimm()
		0FH, 0BAH, 0F8H, 03H;    (* BTC	EAX, 3 *)
	
	PROCEDURE [code] btc_memimm()
		0FH, 0BAH, 038H, 03H;	 (* BTC	DWORD[EAX], 3*)

	PROCEDURE [code] btc_regreg()
		0FH, 0BBH, 0D0H;	       (*BTC	EAX, EDX*)		
		
	PROCEDURE [code] btc_memreg()
		0FH, 0BBH, 010H;	       (*BTC	[EAX], EDX *)	
		

	PROCEDURE btc();
	BEGIN
		btc_regimm;
		btc_memimm;
		btc_regreg;
		btc_memreg
	END btc;	
	
	
	(* bsf*)
	PROCEDURE [code] bsf_regreg()
		0FH, 0BCH, 0C2H;	       (*BSF	EAX, EDX*)		
		
	PROCEDURE [code] bsf_regmem()
		0FH, 0BCH, 02H;	       (*BSF	EAX, [EDX] *)	
		
	PROCEDURE bsf();
	BEGIN
		bsf_regreg;
		bsf_regmem
	END bsf;	
		
	(* bsr*)
	PROCEDURE [code] bsr_regreg()
		0FH, 0BDH, 0C2H;	       (*BSR	EAX, EDX*)		
		
	PROCEDURE [code] bsr_regmem()
		0FH, 0BDH, 02H;	       (*BSR	EAX, [EDX] *)	
				
	PROCEDURE bsr();
	BEGIN
		bsr_regreg;
		bsr_regmem
	END bsr;	
		

	PROCEDURE Do();
		VAR b: BOOLEAN; x, y: INTEGER;
	BEGIN
		//b := S.BIT(x, 31);   (* ok *)
		//b := S.BIT(x, 200); (*wrong here *)
		 
		b := S.BIT(x, y);     (* err  *)
	END Do;
	
	
END TestSystemBit.
you'd better check it after modification;

luowy

Re: SYSTEM.BIT bug

Posted: Sat Nov 23, 2019 12:57 pm
by luowy
Josef Templ wrote:The resulting procudure would look like this
yes, your code is more elegant and correct!
luowy

Re: SYSTEM.BIT bug

Posted: Sat Nov 23, 2019 1:15 pm
by Josef Templ
Thanks a lot for the test code.
I have checked all the examples and they work as expected.

I have also changed the bit offset (-56) into a positive number.

As a small improvement of the generated output I have removed the redundant 0 displacement as for example in 0[eax].

For the changes see https://redmine.blackboxframework.org/p ... der386.odc

- Josef

Re: SYSTEM.BIT bug

Posted: Sat Nov 23, 2019 1:34 pm
by Josef Templ
@luowy, or may be Robert can also do that:
is it possible to change the title of this topic into something like

issue-#204 SYSTEM.BIT bug

I think that the original author can change the topic title in the very first posting of the topic but I am not sure.

- Josef

Re: issue-#204 SYSTEM.BIT bug

Posted: Sat Nov 23, 2019 4:29 pm
by Robert
Josef described SYSTEM.BIT as 'undocumented'. Should an explanation be added to PSI?

Re: issue-#204 SYSTEM.BIT bug

Posted: Tue Nov 26, 2019 6:09 am
by luowy
According intel manual,I think we need to add this patch in DevCPB.StPar1

Code: Select all

| bitfn: (*SYSTEM.BIT*)
			IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
			ELSIF f IN intSet THEN
				IF (x.class = Nconst) THEN (*<<<*)
					IF  (x.conval.intval > DevCPM.MaxSet) THEN  
						n :=x.conval.intval;
						x.conval.intval := n MOD (DevCPM.MaxSet+1);
						n:= n DIV  (DevCPM.MaxSet+1) * SIZE(SET);
						Op(plus,p, NewIntConst(n));
					ELSIF x.conval.intval  < 0 THEN 
						 err(111)
					END;
				END;(* >>>*)
				p := NewOp(Ndop, bit, p, x)
			ELSE err(111)
			END;
			p.typ := DevCPT.booltyp
this patch solved the problom SYSTEM.BIT(x,200), which ouput wrong code currently;
the draft document:

Code: Select all

Name	        Argument types	   Result type	Description
BIT(adr, offset)	adr, offset: integer*	   BOOLEAN	test the offset bit in the adr base bit string  
 
* offset >=0 if const

Re: issue-#204 SYSTEM.BIT bug

Posted: Fri Nov 29, 2019 10:51 am
by luowy
A2 new OberonReport has it Document

Code: Select all

12.2.1 BIT Manipulation
Function     Argument Types         Result Type    Description
BIT(adr,n) adr: ADDRESS;n: INTEGER  BOOLEAN        Returns TRUE if bit n at adr is set, FALSE otherwise

Re: issue-#204 SYSTEM.BIT bug

Posted: Sun Dec 01, 2019 2:19 pm
by Josef Templ
https://css.csail.mit.edu/6.858/2014/readings/i386.pdf says for BT on Page 267 that it always takes the bit offset MOD 32 if it is an immediate operand.

In principle, larger bit offsets are possible by shifting the bit base with the memory address operand but this is currently not
supported by the compiler.

I have not found out if the bit offset is treated as a signed or unsigned number if it is a register.

- Josef