RE: [PATCH v3] serial: make uart_console_write->putchar()'s character an unsigned char

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Maciej W. Rozycki
> Sent: 03 March 2022 09:55
> 
> > > The real problem is that using char (or short) for a function parameter
> > > or result is very likely to require the compile add code to mask
> > > the value to 8 (or 16) bits.
> > >
> > > Remember that almost every time you do anything with a signed or unsigned
> > > char/short variable the compiler has to use the integer promotion rules
> > > to convert the value to int.
> > >
> > > You'll almost certainly get better code if the value is left in an
> > > int (or unsigned int) variable until the low 8 bits get written to
> > > a buffer (or hardware register).
> >
> > So should we use int/uint instead of more appropriate shorter types everywhere
> > now? The answer is: definitely not. The assembly on x86 looks good (it uses
> > movz, no ands), RISC architectures have to do what they chose to.
> 
>  We do have an issue, because we still have this:
> 
> void uart_console_write(struct uart_port *port, const char *s,
> 			unsigned int count,
> 			void (*putchar)(struct uart_port *, int))
> 
> and then:
> 
> 		putchar(port, *s);
> 
> there.  Consequently on targets where plain `char' type is signed the
> value retrieved from `*s' has to be truncated in the call to `putchar'.
> And indeed it happens with the MIPS target:
> 
> 803ae47c:	82050000 	lb	a1,0(s0)
> 803ae480:	26100001 	addiu	s0,s0,1
> 803ae484:	02402025 	move	a0,s2
> 803ae488:	0220f809 	jalr	s1
> 803ae48c:	30a500ff 	andi	a1,a1,0xff
> 
> vs current code:
> 
> 803ae47c:	82050000 	lb	a1,0(s0)
> 803ae480:	26100001 	addiu	s0,s0,1
> 803ae484:	0220f809 	jalr	s1
> 803ae488:	02402025 	move	a0,s2
> 
> (NB the last instruction shown after the call instruction, JALR, is in the
> delay slot that is executed before the PC gets updated).  Now arguably the
> compiler might notice that and use an unsigned LBU load instruction rather
> than the signed LB load instruction, which would make the ANDI instruction
> redundant, but still I think we ought to avoid gratuitous type signedness
> changes.
> 
>  So I'd recommend changing `s' here to `const unsigned char *' or, as I
> previously suggested, maybe to `const u8 *' even.

Or just not worry that the 'char' value (either [128..127] or [0..255])
is held in a 'signed int' variable.
That basically happens every time it is loaded into a register anyway.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux